user3772999
user3772999

Reputation: 59

Cannot forward after response has been committed Servlet error

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

Answers (2)

Kumar Abhinav
Kumar Abhinav

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

Alcanzar
Alcanzar

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

Related Questions