So, I have struggled for 2 days to understand what my error is. My drop down list is not populating with data from the database. I am using Java EE and MySQL.
I can insert data in the database without a problem but when i retrieve it for some reason the jsp doesn't do its thing correctly so that I always get the drop down empty.
This is the table I am using:
create table category(
category_id int auto_increment,
name varchar(30),
primary key(category_id)
);
This is the servlet I am using and the method for executing the query. As you can see I am returning a List of objects and then I am adding it as a request attribute in the doGet method. So I guess until here everything should work fine.
public class DropDownServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
try {
List<Category> categories = retrieveCategories();
request.setAttribute("categories", categories);
RequestDispatcher view = request.getRequestDispatcher("viewdropdown.jsp");
view.forward(request, response);
} catch (ClassNotFoundException | SQLException | IOException ex) {
ex.printStackTrace();
}
}
public static List<Category> retrieveCategories() throws ClassNotFoundException, SQLException {
Connection conn = DatabaseConnection.initializeConnection();
String query = "Select * from category";
PreparedStatement pstmnt = conn.prepareStatement(query);
List<Category> categories = new ArrayList<>();
ResultSet rs = pstmnt.executeQuery();
while (rs.next()) {
int id = rs.getInt("category_id");
String name = rs.getString("name");
Category cat = new Category(id,name);
categories.add(cat);
}
conn.close();
return categories;
}
and here is the jsp with the dropdown which doesn't display the data that it should.
<html>
<head>
<title>Dropdown page</title>
</head>
<body>
<h1>The names of the categories are the following:</h1>
<select id ="dropdown">
<c:forEach items="${categories}" var="category">
<option value = "${category.name}">${category.name}</option>
</c:forEach>
</select>
<br>
<br>
</body>
</html>
EDIT:
So I have created this hardcoded test method to test my code and I add it as request parameter identically to how I added the other method with the DB query. My DropDown is still empty, so the problem could be from the way I try to display the items in the jsp. I think it could be in the loop I have.
public static List<Category> testMethod(){
List<Category> list = new ArrayList<>();
Category one = new Category(1,"Blue");
Category two = new Category(2,"Red");
list.add(one);
list.add(two);
return list;
}
Looks like the ${categories} is an empty collection.
First, make sure, you have imported the JSTL Core library into your JSP page. This is done by putting
<%# taglib prefix="c" uri = "http://java.sun.com/jsp/jstl/core" %>
at the top of the JSP page.
Additionally, you can check on the JSP side if the collection is empty by adding somewhere:
<c:out value="${categories.size()}" />.
Also, you are using Expression Language directly between the HTML <option> tags, so you will also need adding:
<%# page isELIgnored = "false" %>
at the top of the JSP page to make it evaluable to the appropriate value, instead of rendering plain text.
Related
I'm implementing MVC using JSP and JDBC. I have imported a database class file to my JSP file and I would like to show the data of a DB table. I don't know how I should return the ResultSet from the Java class to the JSP page and embed it in HTML.
How can I achieve this?
In a well designed MVC approach, the JSP file should not contain any line of Java code and the servlet class should not contain any line of JDBC code.
Assuming that you want to show a list of products in a webshop, the following code needs to be created.
A Product class representing a real world entity of a product, it should be just a Javabean.
public class Product {
private Long id;
private String name;
private String description;
private BigDecimal price;
// Add/generate getters/setters/c'tors/equals/hashcode boilerplate.
}
A DAO class which does all the nasty JDBC work and returns a nice List<Product>.
public class ProductDAO {
private DataSource dataSource;
public ProductDAO(DataSource dataSource) {
this.dataSource = dataSource;
}
public List<Product> list() throws SQLException {
List<Product> products = new ArrayList<Product>();
try (
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT id, name, description, price FROM product");
ResultSet resultSet = statement.executeQuery();
) {
while (resultSet.next()) {
Product product = new Product();
product.setId(resultSet.getLong("id"));
product.setName(resultSet.getString("name"));
product.setDescription(resultSet.getString("description"));
product.setPrice(resultSet.getBigDecimal("price"));
products.add(product);
}
}
return products;
}
}
A servlet class which obtains the list and puts it in the request scope.
#WebServlet("/products")
public class ProductsServlet extends HttpServlet {
#Resource(name="jdbc/YourDB") // For Tomcat, define as <Resource> in context.xml and declare as <resource-ref> in web.xml.
private DataSource dataSource;
private ProductDAO productDAO;
#Override
public void init() {
productDAO = new ProductDAO(dataSource);
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
List<Product> products = productDAO.list();
request.setAttribute("products", products); // Will be available as ${products} in JSP
request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
} catch (SQLException e) {
throw new ServletException("Cannot obtain products from DB", e);
}
}
}
Finally a JSP file in /WEB-INF/products.jsp which uses JSTL <c:forEach> to iterate over List<Product> which is made available in EL by ${products}, and uses JSTL <c:out> to escape string properties in order to avoid XSS holes when it concerns user-controlled input.
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/format" prefix="fmt" %>
...
<table>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.id}</td>
<td><c:out value="${product.name}" /></td>
<td><c:out value="${product.description}" /></td>
<td><fmt:formatNumber value="${product.price}" type="currency" currencyCode="USD" /></td>
</tr>
</c:forEach>
</table>
To get it to work, just call the servlet by its URL. Provided that the servlet is annotated #WebServlet("/products") or mapped in web.xml with <url-pattern>/products</url-pattern>, then you can call it by http://example.com/contextname/products
See also:
How to avoid Java code in JSP files?
doGet and doPost in Servlets
How should I connect to JDBC database / datasource in a servlet based application?
Design Patterns web based applications
RequestDispatcher.forward() vs HttpServletResponse.sendRedirect()
How to map a ResultSet with unknown amount of columns to a List and display it in a HTML table?
How do I pass current item to Java method by clicking a hyperlink or button in JSP page?
MVC, in a web application context, doesn't consist in using a class from a JSP. It consists in using the following model :
browser sends a request to a web server
the web server is configured so that the request is handled by a servlet or a filter (the controller : Java code, not JSP code)
The servlet/filter usually dispatches the request to a specific class (called an Action, the specific part of the controller), based on configuration/annotations
The action executes the business logic (i.e. fetch the data from the database in your example : the model)
The action forwards the request to a JSP. The role of the JSP is only to generate HTML code (i.e. display your data : the view)
Since the JSP usually uses JSP tags (the JSTL, for example) and the JSP expression language, and since JSP tags and the EL are designed to get information from JavaBeans, you'd better have your data available in the form of JavaBeans or collections of JavaBeans.
The role of the controller (the action class) is thus to fetch the data, to create JavaBean instances containing the data, in a suitable format for the JSP, to put them in request attributes, and then to dispatch to the JSP. The JSP will then iterate through the JavaBean instances and display what they contain.
You should not implement the MVC framework yourself. Use existing ones (Stripes, Struts, etc.)
I don't know how should I return the ResultSet from the class file to the JSP page
Well, you don't.
The point of MVC is to separate your model ( the M DB info in this case ) from your view ( V a jsp, in this case ) in such a way you can change the view without braking to application.
To do this you might use an intermediate object to represent your data ( usually called DTO - after Data Transfer Object -, don't know how they call it these days ), and other object to fetch it ( usually a DAO ).
So basically you have your JSP file, get the request parameters, and then invoke a method from the DAO. The dao, internally has the means to connect to the db and fetch the data and builds a collections of DTO's which are returned to the JSP for rendering.
Something like this extremely simplified ( and insecure ) code:
Employee.java
class Employee {
String name;
int emplid;
}
EmployeeDAO.java
class EmployeeDAO {
... method to connect
etc.
List<Employee> getAllNamed( String name ) {
String query = "SELECT name, emplid FROM employee where name like ?";
ResultSet rs = preparedStatement.executeQuery etc etc.
List<Employee> results = ....
while( rs.hasNext() ) {
results.add( new Employee( rs.getString("name"), rs.getInt("emplid")));
}
// close resources etc
return results;
}
}
employee.jsp
<%
request.setAttribute("employees", dao.getAllNamed( request.getParameter("name") );
%>
<table>
<c:forEach items="${employees}" var="employee">
<tr><td>${employee.emplid}</td><td>${employee.name}</td></tr>
</c:forEach>
</table>
I hope this give you a better idea.
I have a problem. I don't understand clearly the code. I have a similar problem with my code.
I have created database SQL and filled up. Then I want to implement a MainServlet (code below) that richieve data from database and in a different jsp page, I want to insert that data in section like h1, h2 ecc... I must use the ${} sintax but I don't know how do that.
Briefly, In jsp file (code below, I MUST USE ${} SINTAX) I want to "call" MainServlet and there I want to richieve data from database and view in jsp file.
I hope I have explained correctly, thank you very much!
MainServlet.java
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class MainServlet
*/
#WebServlet({ "/MainServlet" })
public class MainServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final String PATH_JSP = "/WEB-INF/";
/**
* #see HttpServlet#HttpServlet()
*/
public MainServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
}
/**
* #see Servlet#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String doveAndare = request.getParameter("azione");
if(doveAndare==null)
doveAndare = "index";
try {
String driverString = "com.mysql.cj.jdbc.Driver";
Class.forName(driverString);
String connString = "jdbc:mysql://localhost:3306/ldd_jewels?user=root&password=";
Connection conn = DriverManager.getConnection(connString);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM JEWEL");
while (rs.next() == true) {
System.out.println(rs.getString("Category") + "\t" + rs.getString("Name"));
/* I try that but does not work
request.setAttribute("name", rs.getString("Name"));
javax.servlet.RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/widering_male.jsp");
dispatcher.forward(request, response); */
}
stmt.close();
conn.close();
} catch(Exception e) {
e.printStackTrace();
}
request.getRequestDispatcher(PATH_JSP+doveAndare+".jsp").forward(request, response);
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
doublerow.jsp
<section id="portfolio-details" class="portfolio-details">
<div class="container">
<div class="row gy-4">
<div class="col-lg-8">
<div class="portfolio-details-slider swiper">
<div class="swiper-wrapper align-items-center">
<div class="swiper-slide">
<img src="assets/img/jewels/doublerow_1.jpg" alt="" />
</div>
<div class="swiper-slide">
<img src="assets/img/jewels/doublerow_2.jpg" alt="" />
</div>
<div class="swiper-slide">
<img src="assets/img/jewels/doublerow_3.jpg" alt="" />
</div>
</div>
<div class="swiper-pagination"></div>
</div>
</div>
<div class="col-lg-4">
<div class="portfolio-info">
<h3>Product details</h3>
<ul>
<li><strong>Code</strong>: 1S3D5</li>
<li><strong>Category</strong>: Bracelets</li>
<li><strong>Name</strong>: Double Row Hinged Bangle</li>
<li><strong>Gender</strong>: Female</li>
<li><strong>Material</strong>: Yellow gold</li>
<li><strong>Size</strong>: 121mm</li>
<li><strong>Price</strong>: €5500</li>
</ul>
</div>
<div class="portfolio-description">
<h2>Description of product</h2>
<p>
The entwined ends of Tiffany Knot’s signature motif symbolize
the power of connections between people. Balancing strength
and elegance, each Tiffany Knot design is a complex feat of
craftsmanship. This bangle is crafted with yellow gold and
polished by hand for high shine. Wear on its own or partnered
with classic silhouettes for an unexpected pairing.
</p>
</div>
</div>
</div>
</div>
</section>
This is my database:
I want to insert each jewel in different pages (each jewel have a jsp file)
You can use the <c:forEach > tag
you can find a detailed example in the following link example use
I think it will be better for you to contain the data of the table into a collection such as list and return the list from the Java class and reuse this collection in the JSP.
I'm implementing MVC using JSP and JDBC. I have imported a database class file to my JSP file and I would like to show the data of a DB table. I don't know how I should return the ResultSet from the Java class to the JSP page and embed it in HTML.
How can I achieve this?
In a well designed MVC approach, the JSP file should not contain any line of Java code and the servlet class should not contain any line of JDBC code.
Assuming that you want to show a list of products in a webshop, the following code needs to be created.
A Product class representing a real world entity of a product, it should be just a Javabean.
public class Product {
private Long id;
private String name;
private String description;
private BigDecimal price;
// Add/generate getters/setters/c'tors/equals/hashcode boilerplate.
}
A DAO class which does all the nasty JDBC work and returns a nice List<Product>.
public class ProductDAO {
private DataSource dataSource;
public ProductDAO(DataSource dataSource) {
this.dataSource = dataSource;
}
public List<Product> list() throws SQLException {
List<Product> products = new ArrayList<Product>();
try (
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT id, name, description, price FROM product");
ResultSet resultSet = statement.executeQuery();
) {
while (resultSet.next()) {
Product product = new Product();
product.setId(resultSet.getLong("id"));
product.setName(resultSet.getString("name"));
product.setDescription(resultSet.getString("description"));
product.setPrice(resultSet.getBigDecimal("price"));
products.add(product);
}
}
return products;
}
}
A servlet class which obtains the list and puts it in the request scope.
#WebServlet("/products")
public class ProductsServlet extends HttpServlet {
#Resource(name="jdbc/YourDB") // For Tomcat, define as <Resource> in context.xml and declare as <resource-ref> in web.xml.
private DataSource dataSource;
private ProductDAO productDAO;
#Override
public void init() {
productDAO = new ProductDAO(dataSource);
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
List<Product> products = productDAO.list();
request.setAttribute("products", products); // Will be available as ${products} in JSP
request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
} catch (SQLException e) {
throw new ServletException("Cannot obtain products from DB", e);
}
}
}
Finally a JSP file in /WEB-INF/products.jsp which uses JSTL <c:forEach> to iterate over List<Product> which is made available in EL by ${products}, and uses JSTL <c:out> to escape string properties in order to avoid XSS holes when it concerns user-controlled input.
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/format" prefix="fmt" %>
...
<table>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.id}</td>
<td><c:out value="${product.name}" /></td>
<td><c:out value="${product.description}" /></td>
<td><fmt:formatNumber value="${product.price}" type="currency" currencyCode="USD" /></td>
</tr>
</c:forEach>
</table>
To get it to work, just call the servlet by its URL. Provided that the servlet is annotated #WebServlet("/products") or mapped in web.xml with <url-pattern>/products</url-pattern>, then you can call it by http://example.com/contextname/products
See also:
How to avoid Java code in JSP files?
doGet and doPost in Servlets
How should I connect to JDBC database / datasource in a servlet based application?
Design Patterns web based applications
RequestDispatcher.forward() vs HttpServletResponse.sendRedirect()
How to map a ResultSet with unknown amount of columns to a List and display it in a HTML table?
How do I pass current item to Java method by clicking a hyperlink or button in JSP page?
MVC, in a web application context, doesn't consist in using a class from a JSP. It consists in using the following model :
browser sends a request to a web server
the web server is configured so that the request is handled by a servlet or a filter (the controller : Java code, not JSP code)
The servlet/filter usually dispatches the request to a specific class (called an Action, the specific part of the controller), based on configuration/annotations
The action executes the business logic (i.e. fetch the data from the database in your example : the model)
The action forwards the request to a JSP. The role of the JSP is only to generate HTML code (i.e. display your data : the view)
Since the JSP usually uses JSP tags (the JSTL, for example) and the JSP expression language, and since JSP tags and the EL are designed to get information from JavaBeans, you'd better have your data available in the form of JavaBeans or collections of JavaBeans.
The role of the controller (the action class) is thus to fetch the data, to create JavaBean instances containing the data, in a suitable format for the JSP, to put them in request attributes, and then to dispatch to the JSP. The JSP will then iterate through the JavaBean instances and display what they contain.
You should not implement the MVC framework yourself. Use existing ones (Stripes, Struts, etc.)
I don't know how should I return the ResultSet from the class file to the JSP page
Well, you don't.
The point of MVC is to separate your model ( the M DB info in this case ) from your view ( V a jsp, in this case ) in such a way you can change the view without braking to application.
To do this you might use an intermediate object to represent your data ( usually called DTO - after Data Transfer Object -, don't know how they call it these days ), and other object to fetch it ( usually a DAO ).
So basically you have your JSP file, get the request parameters, and then invoke a method from the DAO. The dao, internally has the means to connect to the db and fetch the data and builds a collections of DTO's which are returned to the JSP for rendering.
Something like this extremely simplified ( and insecure ) code:
Employee.java
class Employee {
String name;
int emplid;
}
EmployeeDAO.java
class EmployeeDAO {
... method to connect
etc.
List<Employee> getAllNamed( String name ) {
String query = "SELECT name, emplid FROM employee where name like ?";
ResultSet rs = preparedStatement.executeQuery etc etc.
List<Employee> results = ....
while( rs.hasNext() ) {
results.add( new Employee( rs.getString("name"), rs.getInt("emplid")));
}
// close resources etc
return results;
}
}
employee.jsp
<%
request.setAttribute("employees", dao.getAllNamed( request.getParameter("name") );
%>
<table>
<c:forEach items="${employees}" var="employee">
<tr><td>${employee.emplid}</td><td>${employee.name}</td></tr>
</c:forEach>
</table>
I hope this give you a better idea.
I have a problem. I don't understand clearly the code. I have a similar problem with my code.
I have created database SQL and filled up. Then I want to implement a MainServlet (code below) that richieve data from database and in a different jsp page, I want to insert that data in section like h1, h2 ecc... I must use the ${} sintax but I don't know how do that.
Briefly, In jsp file (code below, I MUST USE ${} SINTAX) I want to "call" MainServlet and there I want to richieve data from database and view in jsp file.
I hope I have explained correctly, thank you very much!
MainServlet.java
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class MainServlet
*/
#WebServlet({ "/MainServlet" })
public class MainServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final String PATH_JSP = "/WEB-INF/";
/**
* #see HttpServlet#HttpServlet()
*/
public MainServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
}
/**
* #see Servlet#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String doveAndare = request.getParameter("azione");
if(doveAndare==null)
doveAndare = "index";
try {
String driverString = "com.mysql.cj.jdbc.Driver";
Class.forName(driverString);
String connString = "jdbc:mysql://localhost:3306/ldd_jewels?user=root&password=";
Connection conn = DriverManager.getConnection(connString);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM JEWEL");
while (rs.next() == true) {
System.out.println(rs.getString("Category") + "\t" + rs.getString("Name"));
/* I try that but does not work
request.setAttribute("name", rs.getString("Name"));
javax.servlet.RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/widering_male.jsp");
dispatcher.forward(request, response); */
}
stmt.close();
conn.close();
} catch(Exception e) {
e.printStackTrace();
}
request.getRequestDispatcher(PATH_JSP+doveAndare+".jsp").forward(request, response);
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
doublerow.jsp
<section id="portfolio-details" class="portfolio-details">
<div class="container">
<div class="row gy-4">
<div class="col-lg-8">
<div class="portfolio-details-slider swiper">
<div class="swiper-wrapper align-items-center">
<div class="swiper-slide">
<img src="assets/img/jewels/doublerow_1.jpg" alt="" />
</div>
<div class="swiper-slide">
<img src="assets/img/jewels/doublerow_2.jpg" alt="" />
</div>
<div class="swiper-slide">
<img src="assets/img/jewels/doublerow_3.jpg" alt="" />
</div>
</div>
<div class="swiper-pagination"></div>
</div>
</div>
<div class="col-lg-4">
<div class="portfolio-info">
<h3>Product details</h3>
<ul>
<li><strong>Code</strong>: 1S3D5</li>
<li><strong>Category</strong>: Bracelets</li>
<li><strong>Name</strong>: Double Row Hinged Bangle</li>
<li><strong>Gender</strong>: Female</li>
<li><strong>Material</strong>: Yellow gold</li>
<li><strong>Size</strong>: 121mm</li>
<li><strong>Price</strong>: €5500</li>
</ul>
</div>
<div class="portfolio-description">
<h2>Description of product</h2>
<p>
The entwined ends of Tiffany Knot’s signature motif symbolize
the power of connections between people. Balancing strength
and elegance, each Tiffany Knot design is a complex feat of
craftsmanship. This bangle is crafted with yellow gold and
polished by hand for high shine. Wear on its own or partnered
with classic silhouettes for an unexpected pairing.
</p>
</div>
</div>
</div>
</div>
</section>
This is my database:
I want to insert each jewel in different pages (each jewel have a jsp file)
You can use the <c:forEach > tag
you can find a detailed example in the following link example use
I think it will be better for you to contain the data of the table into a collection such as list and return the list from the Java class and reuse this collection in the JSP.
I have an Employee management application that can perform operations on tables in the database.
My problem is when i try to delete a parent record (department record) it doesn't delete it because the department has employees in it , but it doesn't also notify the user .
i want a way to handle this , a popup message or print exception description on the screen , something like that.
it maybe an easy problem but am new to programming , can you please help .
Thanks in advance
this is the deleteMethod from DepartmentDao.java :
public void deleteDepartment(int deptno) {
try {
PreparedStatement preparedStatement = connection.prepareStatement("delete from dept where deptno=?");
preparedStatement.setInt(1, deptno);
preparedStatement.executeUpdate();
} catch (SQLException e) {
}// catch
} // deleteDepartment
this is the DepartmentController.java :
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String forward = "";
String action = request.getParameter("action");
if (action.equalsIgnoreCase("insert")) {
forward = ADD_DEPARTMENT;
} else if (action.equalsIgnoreCase("delete")) {
int deptNo = Integer.parseInt(request.getParameter("deptno").trim());
deptDao.deleteDepartment(deptNo);
forward = DEPARTMENTS;
here's the DepartmentUpdate.jsp
<!DOCTYPE html>
<%# page contentType="text/html;charset=windows-1256"%>
<%# page import="java.io.*,java.util.*,java.sql.*"%>
<%# page import="javax.servlet.http.*,javax.servlet.*" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1256"/>
<link rel="stylesheet" type="text/css" href="resources/css/styles.css" />
</head>
<body>
<form method="POST" action='departmentcontroller' name="frmAddUser">
<input type="hidden" name="theAction" value="update">
<table align="center">
<tr><th colspan="2">Update Department</th></tr>
<tr><td>Department Number : </td><td><input type="text" name ="deptno" value="<%=request.getAttribute("deptno")%>" disabled="disabled"></td></tr>
<tr><td>Department Name</td><td><input type="text" name="dname" value="<%=request.getAttribute("dname")%>"></td></tr>
<tr><td>Location</td><td><input type="text" name="loc"></td></tr>
<tr><td colspan="2"> <input type="submit" name="updateDepartment" value="Update"></td></tr>
</table>
</form>
</body>
</html>
As far I understood the problem you want to notify the user of the exception occurred at server side.
*As other mentioned you should not swallow the exception after catching it.
After catching the exception check for the message by **e.getMessage() if it is similar to parent record existing(or whatever you are getting that) then you can do one of the following***
send a flag of exception occurred during processing and the error
message also from your JDBC helper to Service class to presentation
layer.
create a custom exception and throw the exception from the catch
block of the jdbc helper. Your custom exception should have the
message and display that message on your jsp.
You can also have generic error page and can redirect to there (But
it will not be suitable in this situation).
Reference for creating your custom exception - How can I write custom Exceptions?
You have to use try..catch block to handle SQLException as below.
} catch (SQLException e) {
response.sendError(422,"Department cannot be deleted. Because the department has employees in it. ");
}
OR
Redirect to a error page you created
}
catch(SQLException e) {
response.sendRedirect("error.jsp?e="+URLEncoder.encode("Department cannot be deleted. Because the department has employees in it.", "UTF-8"))
}
and in the error.jsp file, display it with
<%= request.getParameter("e") %>
I was trying to forward from doPost to doGet of the ControllerServlet urlPattern = "/remove_person", so I can re-update findAll query inside my doGet method of the ControllerServlet class, and then forward to remove_person.jsp from doGet method, but AS-WEB-CORE-00089 exception is thrown
WARNING: StandardWrapperValve[ControllerServlet]: Servlet.service() for servlet ControllerServlet threw exception
javax.servlet.ServletException: AS-WEB-CORE-00089
at org.apache.catalina.core.ApplicationDispatcher.doInvoke(ApplicationDispatcher.java:863)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:739)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:575)
at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:546)
at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:428)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:378)
at server.ControllerServlet.doPost(ControllerServlet.java:130)
where ControllerServlet.java:130 line is in doPost() method:
request.getRequestDispatcher(url).forward(request, response);
Here is the code of servlet class:
#WebServlet(
name = "ControllerServlet",
loadOnStartup = 1,
urlPatterns = {
"/index",
"/search_person",
"/add_person",
"/remove_person"})
public class ControllerServlet extends HttpServlet {
#PersistenceUnit
private EntityManagerFactory emf;
#Resource
private UserTransaction utx;
private EntityManager em;
#Override
public void init() throws ServletException {
assert emf != null;
em = emf.createEntityManager();
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String servletPath = request.getServletPath();
if (servletPath.equals("/index")) {
}
else if (servletPath.equals("/search_person")) {
List persons = em.createNamedQuery("Person.findAll").getResultList();
request.setAttribute("findByNameAndYearBirth", persons);
}
else if (servletPath.equals("/add_person")) {
}
else if (servletPath.equals("/remove_person")) {
List persons = em.createNamedQuery("Person.findAll").getResultList();
request.setAttribute("findAll", persons);
}
String url = servletPath + ".jsp";
request.getRequestDispatcher(url).forward(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String servletPath = request.getServletPath();
if (servletPath.equals("/index")) {
}
else if (servletPath.equals("/search_person")) {
String name = request.getParameter("name");
String yearBirth = request.getParameter("yearBirth");
Query query = em.createNamedQuery("Person.findAll");
if (!name.isEmpty() && !yearBirth.isEmpty()) {
query = em.createNamedQuery("Person.findByNameAndYearBirth");
query.setParameter("name", name);
query.setParameter("yearBirth", Short.parseShort(yearBirth));
}
else if (!name.isEmpty()) {
query = em.createNamedQuery("Person.findByModel");
query.setParameter("name", name);
}
else if (!yearBirth.isEmpty()) {
try {
Short sYearBirth = Short.parseShort(yearBirth);
query = em.createNamedQuery("Person.findByYearBirth");
query.setParameter("yearBirth", sYearBirth);
} catch (NumberFormatException nfe) {}
}
List persons = query.getResultList();
request.setAttribute("findByNameAndYearBirth", persons);
}
else if (servletPath.equals("/add_person")) {
String name = request.getParameter("name");
String hobby = request.getParameter("hobby");
String yearBirth = request.getParameter("yearBirth");
int personsLen = em.createNamedQuery("Person.findAll").getResultList().size();
Person newPerson = new Person(
++personsLen, name, hobby, Short.parseShort(yearBirth)
);
try {
utx.begin();
em = emf.createEntityManager();
em.persist(newPerson);
utx.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
else if (servletPath.equals("/remove_person")) {
String id = request.getParameter("id");
Person person = null;
try {
utx.begin();
person = em.find(Person.class, Integer.parseInt(id));
em.remove(person);
utx.commit();
} catch (Exception e) {
e.printStackTrace();
}
servletPath = "/remove_person";
}
String url = servletPath;
request.getRequestDispatcher(url).forward(request, response);
}
}
Problem is, my line inside doPost method
String url = path;
does not contain a ".jsp" part.
But if I add ".jsp" part to a string url, then how I will update findAll query data inside remove_person.jsp if i don't go to servlet doGet first to collect new data after adding or deleting entities?
remove_person.jsp
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h1>Remove Person</h1>
<form action="remove_person" method="post">
<table border="3">
<tr>
<th>ID</th>
<th>Name</th>
</tr>
<c:forEach var="person" begin="0" items="${findAll}">
<tr>
<td>${person.id}</td>
<td>${person.name}</td>
</tr>
</c:forEach>
</table>
<strong>Remove person: </strong>
<select name="id">
<c:forEach var="person" items="${findAll}">
<option value="${person.id}">${person.id}. ${person.name} </option>
</c:forEach>
</select>
<input type="submit" id="remove_person" value="Remove" />
</form>
<br>
Home page
</body>
</html>
Actually, is it even possible to forward from doPost to doGet method of the same servlet ? The reason I was trying to do this is because, inside doGet I already use this code:
List persons = em.createNamedQuery("Person.findAll").getResultList();
request.setAttribute("findAll", persons);
So why should I duplicate this code inside doPost method, when I can forward from doPost to doGet method and invoke that code?
UPDATE:
Bad approach:
String url = servletPath;
request.getRequestDispatcher(url).forward(request, response);
Correct approach:
String url = request.getContextPath() + servletPath;
response.sendRedirect(url);
Use redirect instead of forward. The pattern (called Post/Redirect/Get) is:
1) the client calls the post url, which does your update
2) the servlet sends a redirect to the client with the url for the get.
3) the client calls the url from the redirect.
When the response from the GET comes back the browser has the GET url, so the browser ends up with a url that's bookmarkable. Also this way the user can't repost the same data by hitting f5 or clicking multiple times.
For when to use forward vs redirect see this advice:
Forward
a forward is performed internally by the servlet
the browser is completely unaware that it has taken place, so its original URL remains intact
any browser reload of the resulting page will simple repeat the original request, with the original URL
Redirect
a redirect is a two step process, where the web application instructs the browser to fetch a second URL, which differs from the
original
a browser reload of the second URL will not repeat the original request, but will rather fetch the second URL
redirect is marginally slower than a forward, since it requires two browser requests, not one
objects placed in the original request scope are not available to the second request
In general, a forward should be used if the operation can be safely repeated upon a browser reload of the resulting web page; otherwise, redirect must be used. Typically, if the operation performs an edit on the datastore, then a redirect, not a forward, is required. This is simply to avoid the possibility of inadvertently duplicating an edit to the database.
i am a beginer and am currently working on my final school project which require retrieving data from a database table and displaying the datas in an html page. i have searched alot but still no progress. i was linked to this site through google, i saw a format and i try to do the same thing but after running the code i get this error
Exception report
message An exception occurred processing JSP page /crimeinfo.jsp at line 32 description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.apache.jasper.JasperException: An exception occurred processing JSP page /crimeinfo.jsp at line 32
29:
30:
31: <%List <String> data =(List)request.getAttribute("data");
32: Iterator <String> itr = data.iterator() ;
33: for (itr = data.iterator();
34: itr.hasNext();)
35: {%>
please i need help. i dont known what else to do. thnks...
viewcrime.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--web.xml code-->
<servlet>
<servlet-name>viewcrimereport</servlet-name>
<servlet-class>viewcrimereport</servlet-class>
<servlet-mapping>
<servlet-name>viewcrimereport</servlet-name>
<url-pattern>viewcrimereport</url-pattern>
</servlet-mapping></servlet>
viewcrimereport.java
public class viewcrimereport extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
private ServletConfig config;
String page = "crimeinfo.jsp";
public void init(ServletConfig config)
throws ServletException{
this.config = config; }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out=response.getWriter();
response.setContentType("text/html");
Connection conn = null;
String url = "jdbc:mysql://localhost/citycrime";
String userName = "root";
String passw = "jids";
PreparedStatement pst = null;
ResultSet rs;
ArrayList<String> datalist = new ArrayList<String>();
try{
int i=0;
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection(url, userName, passw);
pst = conn.prepareStatement("");
String sql ="select suspectname,suspectaliases,suspectht,suspectgender,features,crimeaddress,crimetype,caseno,casestatus from crimereport";
pst.executeQuery(sql);
rs = pst.getResultSet();
while(rs.next()){
datalist.add(rs.getString("suspectname"));
datalist.add(rs.getString("suspectaliases"));
datalist.add(rs.getString("suspectht"));
datalist.add(rs.getString("suspectgender"));
datalist.add(rs.getString("features"));
datalist.add(rs.getString("crimeaddress"));
datalist.add(rs.getString("crimetype"));
datalist.add(rs.getString("caseno"));
datalist.add(rs.getString("casestatus"));}
rs.close();pst.close(); }
catch(Exception e){System.out.println("Exception is;"+e);}
request.setAttribute("data",datalist);
RequestDispatcher dispatcher = request.getRequestDispatcher(page);
if (dispatcher != null){
dispatcher.forward(request, response);
}
}
}
crimeinfo.jsp
<%# page language="java" import="java.sql.*" import="java.util.*"
contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4
/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Crime Report</title>
</head>
<body>
<table border="1" with="600">
<tr><td><tb><td>SuspectName</td></b>
<td><tb>SuspectAlias</b></td>
<td><tb>suspectaliases</tb></td>
<td><tb>Height</tb></td>
<td><tb>suspectht</tb></td>
<td><tb>Gender</tb></td>
<td><tb>suspectgender</tb></td>
<td><tb>Features</tb></td>
<td><tb>features</tb></td>
<td><tb>Address</tb></td>
<td><tb>crimeaddress</tb></td>
<td><tb>CrimeType</tb></td>
<td><tb>crimetype</tb></td>
<td><tb>CaseNumber</tb></td>
<td><tb>caseno</tb></td>
<td><tb>Status</tb></td>
<td><tb>casestatus</tb></td></tr>
<% Iterator <String> itr;%>
<%List data =(List)request.getAttribute("datalist");
for (itr = data.iterator();
itr.hasNext();){%><tr>
<%String s =(String)itr.next(); %>
<td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td>
<tr><td><%=itr.next()%>></td></tr><%} %>
</table>
</body>
</html>
At line 32, make it Iterator itr = data.iterator() ; I advise you to use while(itr.hasNext() instaed of for loop for more clarity of the code. Also, the initialization part in the for loop is retundant.
rename your xml file to web.xml and put it as \WEB-INF\web.xml
in web.xml, url-pattern should be <url-pattern>/viewcrimereport</url-pattern>
for your servlet, since you have already extended HttpServlet class, there is no need to implement Servlet interface. HttpServlet class already implements that interface
you have not closed your connection. use conn.close().
in your jsp, it should be <%List data =(List)request.getAttribute("data"); because you have set request attribute with name data and not "datalist"
use of scriptlets (those <% %> things) are discouraged. see this
since you are not outputting anything from your servlet to your browser, you can omit the following code PrintWriter out=response.getWriter();
response.setContentType("text/html");
in my personal opinion, i would suggest to use service instead of doGet(). Service method will itself call the doGet method. Plus it can also invoke other meyhods like doPost, doHead etc if it requires.
You can use the datalist.get(column index) method of ArrayList. For more details refer to:
http://www.tutorialspoint.com/java/java_arraylist_class.htm