問題描述:

錯誤原因:
該異常表示,目前對用戶端的響應已經結束,不能在響應已經結束(或說消亡)後再向 用戶端(實際上是緩沖區)輸出任何内容。
具體分析:
首先解釋下flush(),我們知道在使用讀寫流的時候資料先被讀入記憶體這個緩沖區中,然後再寫入檔案,但是當資料讀完時不代表資料已經寫入檔案完畢,因為可能還有一部分仍未寫入檔案而留在記憶體中,這時調用flush()方法就會把緩沖區的資料強行清空輸出,是以flush()的作用就是保證緩存清空輸出。
response是服務端對用戶端請求的一個響應,其中封裝了響應頭、狀态碼、内容等,服務端在把response送出到用戶端之前,會向緩沖區内寫入響應頭和狀态碼,然後将所有内容flush。這就标志着該次響應已經committed(送出)。對于目前頁面中 已經committed(送出)的response,就不能再使用這個response向緩沖區寫任何東西(注:同一個頁面中的response.XXX()是同一個response的不同方法,隻要其中一個已經導緻了committed,那麼其它類似方式的調用都會導緻 IllegalStateException異常)。
【注意】能夠導緻響應已經committed的操作包括:forward, redirect, flushBuffer。
JDK API:
①
②
③
備 注:
注:在一次響應commit之前,所有的内容輸出都将寫入servlet引擎的緩沖區(tomcat或weblogic的内容空間), 而在commit之後,上一次response向緩沖區寫入的内容,将清空。由于servlet在沒有設定單線程的情況下(使用Single-Threaded Model,servlet實作 SingleThreadModel接口,jsp使用<%@ page isThreadSafe="false" %>),是多線程的,是以上面所說的緩沖區,都将是該response所屬的線程私有的記憶體空間。有了這個概念, 将可以分析碰到的關于servlet多線程的很多問題。如果不能确認response是否已經committed. 可以調用response.isCommitted()來判斷。導緻這個錯誤最普遍的原因是,jsp有編譯錯誤。
常見解決辦法:
①在response.sendRedirect()方法後加return語句即可,如下:
response.sendRedirect("login.jsp");
return;
②檢查送出的url是否有誤。
③如果你的頁面中用了清緩存代碼response.flushbuffer();又用到了response.sendRedirect(url);你可以把response.flushbuffer();去掉,或者用JS的window.location.href="url" target="_blank" rel="external nofollow" ;來做轉向。
④如果你用了OutputStream,而web容器生成的servlet代碼中有out.write(””),這個和JSP中調用的response.getOutputStream()沖突。out.write()這個是字元流,而response.getOutputStream()是位元組流,你不能在同一個頁面中調用多個輸出流。無論先調用哪一個,在調用第二個時都會抛出IllegalStateException,因為在jsp中,out變量是通過response.getWriter得到的。在多個使用了outputStream的<%%>語句之間不能有空格及多餘的字元。也就是頁面中除了使用了outputStream的<%%>之外不能有空格或其它任何字元,在之内的語句可以有空格及回車。在JSP頁面做輸出的時候有兩種方式.一是通過JspWriter,另一個是通過OutputStream,但二者互相排斥.如果并存的話就會報告以上異常. 在不得不使用OutputStream的時候.我們必須要把JspWriter舍棄掉了。找到請求異常的頁面所對應的Servlet..把其中所有使用JspWriter的語句全部去掉. 或者是到你的JSP檔案裡把動态輸出的代碼注釋掉.這裡注意換行和空格制表符均為JspWriter輸出.應該一起去掉.儲存檔案重新啟動伺服器你會發現上述異常消失了。
由于jsp container在處理完成請求後會調用releasePageContet方法釋放
所用的PageContext object,并且同時調用getWriter方法,由于getWriter方法
與在jsp頁面中使用流相關的getOutputStream方法沖突,是以會造成這種異常,
解決辦法是:隻需要在jsp頁面的最後加上兩條語句:
out.clear();
out=pageContext.pushBody();
即可(其中out,pageContext均為jsp内置對象!) 。
版權聲明:本文為CSDN部落客「weixin_34080571」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。
原文連結:https://blog.csdn.net/weixin_34080571/article/details/92388261