对于初学者来说,一个常见的误解是:当调用 forward() 或者 sendRedirect() 时控制流将会自动跳出原函数。标题所示错误通常是基于此误解而引起的。
示例代码:
class="java" name="code">protected void doPost() {
if (someCondition) {
sendRedirect();
}
forward(); // This is STILL invoked when someCondition is true!}
forward() 和 sendRedirect() 与system.exit() 不同,当上例中的 someCondition为true时,很有可能得到此异常:
IllegalStateException: Cannot forward a response that is already committed
为了解决此问题,可以在sendRedirect() / forward() 之后加上 return;
protected void doPost() {
if (someCondition) {
sendRedirect();
return;
}
forward();}
?
?或者把后一个forward() 放入else中
protected void doPost() {
if (someCondition) {
sendRedirect();
return;
}
forward();}
上文所述是引起该异常的最常见的情况;近日在一个由服务器下载文件函数中避免了上述问题,但仍然出现了此异常。除去冗余部分的函数如下:
public void download(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
...
OutputStream out = response.getOutputStream();
try {
...
out.write();
} catch (Exception e){
log.error(e.getMessage());
} finally {
if (out!=null ){
out.flush();
out.close();
}
...
forward();
}
Server端在提交response到Client端之前会向一个缓冲区写入相应头和状态码,然后将内容清空。而一旦缓冲区被清空就标志着该response已被提交(response is committed)。于是在finally块中随着out.flush(),该response已被提交了。原因找到,解决方法同上。
Reference:
1.?stackoverflow -?java.lang.IllegalStateException: Cannot forward after response has been committed
2. Cannot forward after response has been committed问题解决及分析
3.?Cannot forward a response that is already committed