java.lang.IllegalStateException:在提交响应之后无法(转发|发送redirect|创build会话)

这个方法抛出

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

初学者之间常见的误解是,他们认为forward()sendRedirect()sendError()的调用会奇迹般地退出并“跳出”方法块,因此忽略了代码的剩余部分。 例如:

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

这实际上是不正确的。 当然,它们的行为与其他任何Java方法(当然期望System#exit()当然)不一样。 当上面例子中的someConditiontrue并且因此在同一个请求/响应中的sendRedirect()sendError() forward()之后调用forward() ,您将有机会得到exception:

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

如果if语句调用forward() ,然后调用sendRedirect()sendError() ,则会抛出以下exception:

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

要解决这个问题,你需要添加一个return; 之后的声明

 protected void doPost() { if (someCondition) { sendRedirect(); return; } forward(); } 

…或者引入一个else块。

 protected void doPost() { if (someCondition) { sendRedirect(); } else { forward(); } } 

要在代码中find根本原因,只需search任何调用forward()sendRedirect()sendError()而不退出方法块或跳过代码的剩余部分的行。 这可以在特定代码行之前的同一个servlet中,也可以在特定servlet之前被调用的任何servlet或filter中。

sendError()情况下,如果您的唯一目的是设置响应状态,请改用setStatus()


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

 protected void doPost() { out.write("some string"); // ... forward(); // Fail! } 

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

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

解决scheme是显而易见的,只是不写入到servlet中的响应。 这是JSP的责任。 你只需像request.setAttribute("data", "some string")那样设置一个request属性,然后在JSP中打印它,就像${data} 。 另请参阅我们的Servlet wiki页面 ,了解如何正确使用Servlet。

也可以看看:

  • “响应已经提交”是什么意思? 那么如何处理exception呢?

您的具体问题无关 ,您的JDBC代码正在泄漏资源。 解决这个问题。 有关提示,请参阅在JDBC中closuresConnection,Statement和ResultSet的频率?

即使添加一个return语句也会引发这个exception,对此,唯一的解决scheme是这个代码:

 if(!response.isCommitted()) // Place another redirection 

通常情况下,如果您已经完成redirect,然后尝试将更多数据输出到输出stream,则会看到此错误。 在过去我已经看到这种情况的情况下,往往是尝试redirect页面的filter之一,然后转发到servlet。 我不能立即看到servlet的任何错误,所以你可能想尝试看看你有的filter。

编辑 :一些更多的帮助诊断问题…

诊断这个问题的第一步是确定抛出exception的位置。 我们假设它正在被线路抛出

 getServletConfig().getServletContext() .getRequestDispatcher("/GroupCopiedUpdt.jsp") .forward(request, response); 

但是,您可能会发现稍后会在代码中抛出它,在尝试执行转发之后,您正试图将其输出到输出stream。 如果来自上述线路,则意味着在该线路之前的某个地方,您可以:

  1. 输出数据到输出stream,或者
  2. 事先做了另一个redirect。

祝你好运!

这是因为你的servlet试图访问一个不存在的请求对象。一个servlet的forward或include语句不会停止方法块的执行。 它继续到方法块或第一个返回语句的结尾,就像任何其他的Java方法。

解决这个问题的最好方法就是根据你的逻辑dynamic设置页面(你认为转发请求的地方)。 那是:

 protected void doPost(request , response){ String returnPage="default.jsp"; if(condition1){ returnPage="page1.jsp"; } if(condition2){ returnPage="page2.jsp"; } request.getRequestDispatcher(returnPage).forward(request,response); //at last line } 

在最后一线只做一次前锋

你也可以在每个forward()之后使用return语句来解决这个问题,或者把每个forward()放在if … else块中

我删除了

  super.service(req, res); 

那对我来说工作得很好

磕碰…

我只是有同样的错误。 我注意到我正在调用super.doPost(request, response); 当重写doPost()方法以及显式调用超类的构造函数时

  public ScheduleServlet() { super(); // TODO Auto-generated constructor stub } 

只要我注释掉了super.doPost(request, response);doPost()语句中,它完美的工作…

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //super.doPost(request, response); // More code here... } 

不用说,我需要重新阅读super()最佳实践:p

在转发或redirectstream程时,应该添加return语句。

例:

如果forwardind,

  request.getRequestDispatcher("/abs.jsp").forward(request, response); return; 

如果redirect,

  response.sendRedirect(roundTripURI); return;