摘自: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/