Reputation: 59
When I run this code, I get an IllegalStateException: Cannot forward after respons has been committed. I apologize, I am new to servlets. What should I do to fix this problem? This occurs at this line:
RequestDispatcher rd = request.getRequestDispatcher("/displayjobs.jsp");
rd.forward(request, response);
Here is the stack trace of the exception:
java.lang.IllegalStateException: Cannot forward after response has been committed
schedule.doGet(schedule.java:71)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
Here is the rest of my servlet code. EDIT: I have also included my jsp code, as I am now experiencing a NPE at line 2:
1 List data = (List)request.getAttribute("jobsData);
2 for(itr = data.iterator(); itr.hasNext();)
This means that for some reason data is null rather than having the information of JobsData.
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String connectionUrl = "jdbc:sqlserver://10.11.1.246;databaseName=Test;integratedSecurity=false;user=sa;password=S0l1dConcepts";
Connection con = DriverManager.getConnection(connectionUrl);
String query = "select * from jobs";
stmt = con.createStatement();
res = stmt.executeQuery(query);
while(res.next()){
list.add(res.getString(1));
list.add(res.getString(2));
list.add(res.getString(3));
list.add(res.getString(4));
list.add(res.getString(5));
list.add(res.getString(6));
list.add(res.getString(7));
list.add(res.getString(8));
list.add(res.getString(9));
list.add(res.getString(10));
}
res.close();
}
catch(Exception e){
RequestDispatcher rd = request.getRequestDispatcher("/error.jsp");
rd.forward(request, response);
}
finally{
request.setAttribute("jData", list);
RequestDispatcher rd = request.getRequestDispatcher("/displayjobs.jsp");
rd.forward(request, response);
list.clear();
out.close();
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String connectionUrl = "jdbc:sqlserver://10.11.1.246;databaseName=Test;integratedSecurity=false;user=sa;password=S0l1dConcepts";
Connection con = DriverManager.getConnection(connectionUrl);
String query = "select * from jobs";
stmt = con.createStatement();
res = stmt.executeQuery(query);
while(res.next()){
list.add(res.getString(1));
list.add(res.getString(2));
list.add(res.getString(3));
list.add(res.getString(4));
list.add(res.getString(5));
list.add(res.getString(6));
list.add(res.getString(7));
list.add(res.getString(8));
list.add(res.getString(9));
list.add(res.getString(10));
}
res.close();
}
catch(Exception e){
RequestDispatcher rd = request.getRequestDispatcher("/error.jsp");
rd.forward(request, response);
}
finally{
request.setAttribute("jData", list);
RequestDispatcher rd = request.getRequestDispatcher("/displayjobs.jsp");
rd.forward(request, response);
list.clear();
out.close();
}
}
}
Here is the JSP code:
<%@page import="java.util.List" %>
<%@page import="java.util.Iterator" %>
<%@ page language="java" 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>Scheduling</title>
</head>
<body>
<table>
<%Iterator itr;%>
<%List data = (List)request.getAttribute("jobsData");
for(itr = data.iterator(); itr.hasNext();){
%>
<tr>
<% String s = (String) itr.next();%>
<td><%=s%></td>
<td><%=itr.next()%></td>
<td><%=itr.next()%></td>
<td><%=itr.next()%></td>
<td><%=itr.next()%></td>
<td><%=itr.next()%></td>
<td><%=itr.next()%></td>
<td><%=itr.next()%></td>
<td><%=itr.next()%></td>
<td><%=itr.next()%></td>
<td><input type="submit" value="Edit" name="edit" onclick ="editRecord(<%=s%> %>);"></td>
<td><input type="submit" value="Delete" name="delete" onclick ="deleteRecord(<%=s%> %>);"></td>
<%} %>
</tr>
</table>
Upvotes: 0
Views: 3512
Reputation: 6675
The problem is simple.The exception is caught,response is delegated from catch block and again from the finally block.
What you should do is have a single place for delegating your response
please note :- A response can be committed only once
boolean exceptionOcured =false;
try{
// your code
}
catch(Exception e){
exceptionOcured =true;
}
finally{
// your code to release resources
}
if(exceptionOcured){
RequestDispatcher rd = request.getRequestDispatcher("/error.jsp");
rd.forward(request, response);
}else{
RequestDispatcher rd = request.getRequestDispatcher("/displayjobs.jsp");
rd.forward(request, response);
}
Upvotes: 1
Reputation: 17155
There are a number of problems with your code... in particular, in the case of an error, you will try to forward twice (once in the catch block and once in the finally block). You should probably add server side logging when you get an exception so that you know there's a problem rather than just tossing the error to the user.
You also have code duplicated between doGet
and doPost
and a resource leak (you aren't closing the database connection or the statement).
Select *
is also a bad idea.
And where is list
defined? If it's defined at the servet class level, your code isn't thread safe.
Upvotes: 1