2011-02-18 48 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转换成便宜货。

(我会发布这个作为评论,但缺乏声誉去做。)