此方法抛出
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);
}
答案 0 :(得分:224)
初学者之间常见的误解是,他们认为forward()
,sendRedirect()
或sendError()
的召唤会神奇地退出并“跳出”方法块,因此忽略代码的残余。例如:
protected void doPost() {
if (someCondition) {
sendRedirect();
}
forward(); // This is STILL invoked when someCondition is true!
}
因此实际上并非如此。它们的行为肯定不同于任何其他Java方法(当然是期望System#exit()
)。如果以上示例中的someCondition
为true
,并且您在同一请求/回复后forward()
或sendRedirect()
之后调用sendError()
,那么机会就是大你会得到例外:
java.lang.IllegalStateException:在提交响应后无法转发
如果if
语句调用forward()
并且您之后调用sendRedirect()
或sendError()
,则会抛出以下异常:
java.lang.IllegalStateException:在提交响应后无法调用sendRedirect()
要解决此问题,您需要在之后添加return;
语句
protected void doPost() {
if (someCondition) {
sendRedirect();
return;
}
forward();
}
...或者引入一个else块。
protected void doPost() {
if (someCondition) {
sendRedirect();
} else {
forward();
}
}
要知道代码中的根本原因,只需搜索调用forward()
,sendRedirect()
或sendError()
的任何行,而不退出方法块或跳过代码的残余。这可以在特定代码行之前的同一个servlet中,也可以在特定servlet之前调用的任何servlet或过滤器中。
如果是sendError()
,如果您的唯一目的是设置回复状态,请改用setStatus()
。
另一个可能的原因是servlet会在调用forward()
时写入响应,或者以相同的方法调用。
protected void doPost() {
out.write("some string");
// ...
forward(); // Fail!
}
大多数服务器的响应缓冲区大小默认为2KB,因此如果你写入超过2KB,那么它将被提交,forward()
将以相同的方式失败:
java.lang.IllegalStateException:在提交响应后无法转发
解决方案很明显,只是不要写入servlet中的响应。这是JSP的责任。您只需设置一个像request.setAttribute("data", "some string")
这样的请求属性,然后在JSP中打印它,就像${data}
一样。另请参阅our Servlets wiki page以了解如何以正确的方式使用Servlet。
无关,你的JDBC代码正在泄漏资源。修复它。有关提示,另请参阅How often should Connection, Statement and ResultSet be closed in JDBC?
答案 1 :(得分:19)
即使添加一个return语句也会出现这个异常,这个代码只有解决方案:
if(!response.isCommitted())
// Place another redirection
答案 2 :(得分:6)
通常,在完成重定向之后,您会看到此错误,然后尝试将更多数据输出到输出流。在我过去看过这种情况的情况下,通常是尝试重定向页面的过滤器之一,然后仍然转发到servlet。我看不出servlet的任何问题,所以你可能想看看你现有的任何过滤器。
编辑:在诊断问题方面有一些帮助...
诊断此问题的第一步是确定抛出异常的确切位置。我们假设它被行抛出
getServletConfig().getServletContext()
.getRequestDispatcher("/GroupCopiedUpdt.jsp")
.forward(request, response);
但是您可能会发现它稍后会在代码中抛出,您尝试在转发之后尝试输出到输出流。如果它来自上面一行,则意味着在此行之前的某处你有:
答案 3 :(得分:2)
这是因为您的servlet正在尝试访问不再存在的请求对象。 servlet的forward或include语句不会停止方法块的执行。它像任何其他java方法一样,一直持续到方法块或第一个返回语句的末尾。
解决此问题的最佳方法是根据您的逻辑动态设置页面(您希望转发请求的位置)。那就是:
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块
中答案 4 :(得分:2)
我删除了
super.service(req, res);
然后它对我来说很好
答案 5 :(得分:2)
...凹凸
我遇到了同样的错误。我注意到在覆盖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
答案 6 :(得分:0)
在转发或重定向流时,您应该添加 return 语句。
示例:
如果是forwardind,
request.getRequestDispatcher("/abs.jsp").forward(request, response);
return;
如果重定向,
response.sendRedirect(roundTripURI);
return;
答案 7 :(得分:0)
在返回前进方法后,您可以简单地执行此操作:
return null;
它将打破目前的范围。