无标题文章
摘自:http://blog.csdn.net/quechao123/article/details/6256653
http://jorton468.blog.163.com/blog/static/72588135201102441617287/
异常一:java.lang.IllegalStateException:Cannot forward a response that is already committed
异常二:IllegalStateException:response already commited
异常三:IllegalStateException:getOutputStream() has already been called for this request
前言:
response是服务端对客户端请求的一个响应,其中封装了响应头、状态码、内容(也就是最终要在浏览器上显示的HTML代码或者其他数据格式)等,
服务端在把response提交到客户端之前,会使用一个缓冲区,并向该缓冲区内写入响应头和状态码,然后将所有内容flush(flush包含两个步骤:先将缓冲区内容发送至客户端,然后将缓冲区清空)。这就标志着该次响应已经committed(提交)。对于当前页面中已经committed(提交)的response,就不能再使用这个response向缓冲区写任何东西(注:以为JSP中,response是一个JSP页面的内置对象,所以同一个页面中的response.XXX()是同一个response的不同方法,只要其中一个已经导致了committed,那么其它类似方式的调用都会导致 IllegalStateException异常)。
对于异常一:
问题描述:
在执行一段代码后,最后执行request.getRequestDispatcher(跳转页面URL).forward(resquest,response)进行页面跳转时,报了此错
问题原因:
1.在forwar之前,response就已经commit到浏览器端了。
导致response commit的原因包括:forward, redirect, flushBuffer
2.前两个原因都是指在forward之前就已经进行了页面跳转动作(forward, redirect)。
至于flushBuffer,每一个JSP页面都有一个缓冲区,默认的缓冲区大小为8KB,如果缓冲区被占满的话,web服务器就会自动将response 进行commit,然后清空缓冲区(即flush),所以再进行页面跳转的时候就会报response已经被commit了。
内置对象out相关方法
public abstract voidclear() throws java.io.IOException清除缓冲区中的内容。如果缓冲区已经被刷新,clear()方法将抛出IOException异常
public abstract voidclearBuffer() throws java.io.IOException清除缓冲区中的当前内容。这个方法和clear()方法的区别是,如果缓冲区已经被刷新,这个方法不会抛出IOException异常
public abstract voidclose() throws java.io.IOException刷新缓冲区,关闭输出流。注意,我们在编写JSP页面时,不需要显式地去调用这个方法,因为在JSP容器所生成的代码中会自动包含对close()方法的调用。
public abstract voidflush() throws java.io.IOException刷新缓冲区,两个步骤:1,提交response 2.清空缓冲区
public intgetBufferSize()获得缓冲区大小,同response.getBufferSize()相同
public abstract intgetRemaining()获得缓冲区中未使用的字节数
public booleanisAutoFlush()判断out对象是否是自动刷新
<%@ page autoFlush="true" %> <%--Default--%>
内置对象response相关方法
response.isCommitted()确认response是否已经committed
response.flushbuffer();同out.flush相同
解决方法:
增大缓冲区大小:
<%@ page buffer="10kb" %>
参考:http://jorton468.blog.163.com/blog/static/72588135201102441617287/