java.lang.IllegalStateException:在提交响应后不能(转发| sendRedirect |创建会话)

san*_*dge 90 servlets response forward illegalstateexception requestdispatcher

抛出此方法

java.lang.IllegalStateException:在提交响应后无法转发

我无法发现问题.有帮助吗?

    int noOfRows = Integer.parseInt(request.getParameter("noOfRows"));
    String chkboxVal = "";
    // String FormatId=null;
    Vector vRow = new Vector();
    Vector vRow1 = new Vector();
    String GroupId = "";
    String GroupDesc = "";
    for (int i = 0; i < noOfRows; i++) {
        if ((request.getParameter("chk_select" + i)) == null) {
            chkboxVal = "notticked";
        } else {
            chkboxVal = request.getParameter("chk_select" + i);
            if (chkboxVal.equals("ticked")) {
                fwdurl = "true";
                Statement st1 = con.createStatement();
                GroupId = request.getParameter("GroupId" + i);
                GroupDesc = request.getParameter("GroupDesc" + i);
                ResultSet rs1 = st1
                        .executeQuery("select FileId,Description from cs2k_Files "
                                + " where FileId like 'M%' and co_code = "
                                + ccode);
                ResultSetMetaData rsm = rs1.getMetaData();
                int cCount = rsm.getColumnCount();

                while (rs1.next()) {
                    Vector vCol1 = new Vector();
                    for (int j = 1; j <= cCount; j++) {
                        vCol1.addElement(rs1.getObject(j));
                    }
                    vRow.addElement(vCol1);
                }
                rs1 = st1
                        .executeQuery("select FileId,NotAllowed from cs2kGroupSub "
                                + " where FileId like 'M%' and GroupId = '"
                                + GroupId + "'" + " and co_code = " + ccode);
                rsm = rs1.getMetaData();
                cCount = rsm.getColumnCount();

                while (rs1.next()) {
                    Vector vCol2 = new Vector();
                    for (int j = 1; j <= cCount; j++) {
                        vCol2.addElement(rs1.getObject(j));
                    }
                    vRow1.addElement(vCol2);
                }

                // throw new Exception("test");

                break;
            }
        }
    }
    if (fwdurl.equals("true")) {
        // throw new Exception("test");
        // response.sendRedirect("cs2k_GroupCopiedUpdt.jsp") ;
        request.setAttribute("GroupId", GroupId);
        request.setAttribute("GroupDesc", GroupDesc);
        request.setAttribute("vRow", vRow);
        request.setAttribute("vRow1", vRow1);
        getServletConfig().getServletContext().getRequestDispatcher(
                "/GroupCopiedUpdt.jsp").forward(request, response);
    }
Run Code Online (Sandbox Code Playgroud)

Bal*_*usC 237

初学者之间常见的误解是他们认为a forward(),sendRedirect()或者sendError()会神奇地退出并"跳出"方法块,因此忽略了代码的残余.例如:

protected void doPost() {
    if (someCondition) {
        sendRedirect();
    }
    forward(); // This is STILL invoked when someCondition is true!
}
Run Code Online (Sandbox Code Playgroud)

因此实际上并非如此.它们的行为肯定不会与任何其他Java方法(System#exit()当然是期望的)不同.当someCondition上面的例子中true你正在调用同一个请求/响应forward()之后sendRedirect()或之后sendError(),那么你将获得异常的机会很大:

java.lang.IllegalStateException:在提交响应后无法转发

如果if语句调用a forward()并且您之后调用sendRedirect()sendError(),则会抛出以下异常:

java.lang.IllegalStateException:在提交响应后无法调用sendRedirect()

要解决此问题,您需要在return;之后添加语句

protected void doPost() {
    if (someCondition) {
        sendRedirect();
        return;
    }
    forward();
}
Run Code Online (Sandbox Code Playgroud)

...或者引入一个else块.

protected void doPost() {
    if (someCondition) {
        sendRedirect();
    } else {
        forward();
    }
}
Run Code Online (Sandbox Code Playgroud)

对于naildown代码中的根本原因,只需搜索任何调用a的行forward(),sendRedirect()或者sendError()不退出方法块或跳过代码的残余.这可以在特定代码行之前的同一个servlet内部,也可以在特定servlet之前调用的任何servlet或过滤器中.

在情况下sendError(),如果你的唯一目的是设置响应状态,用setStatus()代替.


另一个可能的原因是servlet forward()在调用时会写入响应,或者在同一个方法中调用.

protected void doPost() {
    out.write("some string");
    // ... 
    forward(); // Fail!
}
Run Code Online (Sandbox Code Playgroud)

响应缓冲区大小在大多数服务器中默认为2KB,因此如果您向其写入超过2KB,则它将被提交并将forward()以相同的方式失败:

java.lang.IllegalStateException:在提交响应后无法转发

解决方案很明显,只是不要写入servlet中的响应.这是JSP的责任.你只需像这样设置一个请求属性request.setAttribute("data", "some string"),然后像这样在JSP中打印它${data}.另请参阅我们的Servlets维基页面,以了解如何以正确的方式使用Servlet.

也可以看看:


您的具体问题无关,您的JDBC代码正在泄漏资源.修复它.有关提示,请参阅在JDBC中关闭Connection,Statement和ResultSet的频率?

  • 休息一下,你的意思是"休息".这意味着代码在一些`for`或`while`循环中,其中`forward()`在循环期间被重复调用(因此不正确,你应该只在循环之后调用一次 - 或者摆脱循环,因为它显然不需要). (2认同)

小智 19

甚至添加一个return语句会引发这个异常,对此只有解决方案是这个代码:

if(!response.isCommitted())
// Place another redirection
Run Code Online (Sandbox Code Playgroud)


Pau*_*and 6

通常,在完成重定向之后会看到此错误,然后尝试将更多数据输出到输出流.在我过去看过这种情况的情况下,通常是尝试重定向页面的过滤器之一,然后仍然转发到servlet.我看不出servlet的任何问题,所以你可能想看一下你所拥有的任何过滤器.

编辑:在诊断问题方面有一些帮助......

诊断此问题的第一步是确定抛出异常的确切位置.我们假设它被线路抛出

getServletConfig().getServletContext()
                  .getRequestDispatcher("/GroupCopiedUpdt.jsp")
                  .forward(request, response);
Run Code Online (Sandbox Code Playgroud)

但是您可能会发现它稍后会在代码中抛出,您尝试在转发之后尝试输出到输出流.如果它来自上面一行,则意味着在此行之前的某个地方你有:

  1. 将数据输出到输出流,或
  2. 事先做了另一个重定向.

祝好运!