1. 程式人生 > >getOutputStream() has already been called for this response異常

getOutputStream() has already been called for this response異常

剛剛研究專案的時候,遇到這個錯誤。搜了很多資料並自己研究了好久終於算是基本解決了這個問題,在這裡記錄一下。
出現錯誤的原因,說出來很簡單:
     一般都是在JSP中呼叫了:response.getOutputStream();來獲取輸出流。並且有意或者無意的使用了out物件來輸出內容。
 
異常的顯式原因(自身程式碼原因):
1、我們都知道,JSP最終會被翻譯為一個Java類(Servlet),然後在頁面中的所有HTML內容,都是在這個Servlet中的_jspService()方法裡面被輸出的。
輸出的方式是out.write("****");
 
2、又因為JSP頁面中你所有寫的不加"<%%>"這兩個括號的內容都會被自動翻譯為out.write("****");
    1、不加"<%%>"是包括"<%%>"、"<%@%>"、"<%!%>"的內容。
    2、out是JspWriter,字元輸出流。輸出的內容包括全部的HTML,以及你無意中會寫的回車+換行。
 
3、問題出現了:如果你呼叫了response.getOutputStream()來獲取輸出流,又無意中out輸出了("\r\n")(當然,你自己顯示呼叫out更不行了)就會出現錯誤。
錯誤就是getOutputStream() has already been called for this response。
 
異常的真實原因(java設計使然):
jsp中的out物件,在jsp中是通過這句程式碼獲得的:pageContext.getOut();
    1、經過我研究發現:如果你並沒有在JSP中寫需要write的內容(write方法沒有被掉用過),似乎out物件根本就沒有被建立。
    2、一旦JSP中使用了out.write(),那麼pageContext.getOut()就真正的返回了一個JspWriter物件。
    3、這樣就不知道在哪最終呼叫了ServletResponse.getWriter();
    4、又因為你之前呼叫了response.getOutputStream();
    5、這樣最終觸發了3和4方法中相同的異常。
        getWriter():IllegalStateException - if the getOutputStream method has already been called for this response object
        getOutputStream():IllegalStateException - if the getOutputStream method has already been called for this response object
        這兩個方法是不能共存的,在他們的方法定義中也有描述:
        Either this method or getOutputStream() may be called to write the body, not both.
   Either this method or getWriter() may be called to write the body, not both.
 
解決方法:
1、無意中使用了out物件的情況:
仔細查詢頁面中的程式碼,刪除%><%之間的所有內容包括空格和換行符。不能出現所有非Java程式碼的內容。
 
2、確實需要使用out物件也要使用getOutputStream的情況:
在JSP頁面Java程式碼塊的最後加上:out.clear();