2011-02-18 95 views
25

我是否需要從HttpServletResponse中「刷新」OutputStream?我需要刷新servlet輸出流嗎?

我已經看到從Should I close the servlet outputstream?我不需要關閉它,但目前還不清楚是否需要刷新它。我應該從容器中期待它嗎?

protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException { 
    byte[] response = getResponse(); 
    String responseType = getResponseType(); 

    response.setContentLength(response.length); 
    response.setContentType(responseType); 
    response.getOutputStream().write(response); 
    response.getOutputStream().flush(); // yes/no/why? 
} 

回答

37

您不需要。 servletcontainer將沖洗並關閉它。順便說一句,已經隱式調用flush。

另見的Servlet 3.1 specification 5.6章:

5.6響應對象

當響應被關閉的關閉,容器必須立即沖洗在響應緩衝區到客戶端的所有剩餘 內容。以下事件表明servlet已滿足請求並且響應對象將被關閉:

  • 終止服務器的service方法。
  • 在響應的setContentLengthsetContentLengthLong方法中指定的內容數量已大於零且 已寫入響應。
  • 調用sendError方法。
  • 調用sendRedirect方法。
  • 調用AsyncContextcomplete方法。

調用flush仍然運行servlet的服務通常是不僅有利於當你有相同的流多個作家,你要切換的作家(如混合二進制/字符數據文件),或者當你想保持流指針不確定的時間(例如日誌文件)。

+0

這是基於約定(per @ mdrg),還是記錄在某處? – shmosel 2015-05-12 23:11:07

2

猜測您在其他問題中得到的答案在這裏適用:如果它是您的流,請刷新並關閉它。否則,流創建者應該這樣做,除非另有說明。

1
java.lang.Object 
    extended byjava.io.Writer 
     extended byjavax.servlet.jsp.JspWriter 


close 
public abstract void close() 
        throws IOException 
Close the stream, flushing it first. 
This method needs not be invoked explicitly for the initial JspWriter as the code generated by the JSP container will automatically include a call to close(). 

Closing a previously-closed stream, unlike flush(), has no effect. 


Throws: 
IOException - If an I/O error occurs 

============================ 

So, DO NOT close the output stream explicitly. 
0

要指出的一個陰險的例外「不需要刷新」:與IBM WebSphere Application Server的工作和使用響應作家(而非的OutputStream)我發現,我不得不沖洗它;否則我的回覆數據的最後部分丟失了。我猜想IBM的HttpServletResponse類確實會刷新OutputStream,但爲Writer使用單獨的緩衝區,並且不會刷新它。其他應用程序服務器似乎這樣做。

因此,如果您將您的回覆數據發送到編寫器,則刷新它是比較安全的。但是沒有必要將OutputStream轉換成便宜貨。

(我會發布這個作爲評論,但缺乏聲譽去做。)