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()
当然)不一样。 当上面例子中的someCondition
为true
并且因此在同一个请求/响应中的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。 如果来自上述线路,则意味着在该线路之前的某个地方,您可以:
- 输出数据到输出stream,或者
- 事先做了另一个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;