响应已经提交后无法转发Servlet错误

时间:2014-07-30 21:10:25

标签: java sql jsp servlets

当我运行此代码时,我收到IllegalStateException:在提交响应后无法转发。我道歉,我是servlets的新手。我该怎么做才能解决这个问题?这发生在这一行:

RequestDispatcher rd = request.getRequestDispatcher("/displayjobs.jsp");
rd.forward(request, response);

以下是异常的堆栈跟踪:

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)

这是我的servlet代码的其余部分。 编辑:我还包括我的jsp代码,因为我现在正在第2行遇到NPE:

1 List data = (List)request.getAttribute("jobsData);
2 for(itr = data.iterator(); itr.hasNext();)

这意味着由于某种原因,数据为空而不是拥有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();
    }

}

}

这是JSP代码:

<%@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>

2 个答案:

答案 0 :(得分:1)

您的代码存在许多问题...特别是在出现错误的情况下,您将尝试前进两次(一次在catch块中,一次在finally块中)。您应该在获得异常时添加服务器端日志记录,以便您知道存在问题而不仅仅是向用户抛出错误。

您还在doGetdoPost之间复制了代码,并且资源泄漏(您无法关闭数据库连接或语句)。

Select *也是一个坏主意。

list定义在哪里?如果它在servet类级别定义,则代码不是线程安全的。

答案 1 :(得分:1)

问题很简单。捕获异常,响应从catch块委派,再从finally块委派。

您应该做的只是一个地方来委派您的回复

请注意: - 响应只能提交一次

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);
}