34

我需要从 HttpServletResponse 中“刷新”OutputStream 吗?

我已经看到 from to我应该关闭 servlet 输出流吗?我不需要关闭它,但不清楚是否需要冲洗它。我也应该从容器中期待它吗?

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?
}
4

4 回答 4

52

你不需要。servlet 容器将为您刷新并关闭它。顺便说一句,close 已经隐式调用了flush。

另请参阅Servlet 3.1 规范的第 5.6 章:

5.6 响应对象的关闭

当响应关闭时,容器必须立即将响应缓冲区中的所有剩余内容刷新到客户端。以下事件表明 servlet 已满足请求并且将关闭响应对象:

  • serviceservlet 方法的终止。
  • setContentLength响应的or 方法中指定的内容量setContentLengthLong已大于零并已写入响应。
  • sendError方法被调用。
  • sendRedirect方法被调用。
  • complete方法 on被AsyncContext调用。

在仍然运行 servlet 服务的同时调用 flush 通常只有当您在同一流上有多个写入程序并且您想要切换写入程序(例如,具有混合二进制/字符数据的文件),或者当您想要保持流指针打开时才有用对于不确定的时间(例如日志文件)。

于 2011-02-18T18:23:18.120 回答
4

猜猜您在另一个问题中得到的相同答案在这里适用:如果它是您的流,请刷新并关闭它。否则,除非另有说明,否则流创建者应该这样做。

于 2011-02-18T16:14:43.507 回答
2

指出“无需刷新”规则的一个潜在例外:使用 IBM WebSphere Application Server 并使用响应Writer(而不是OutputStream)我发现我必须刷新它;否则我的响应数据的最后一部分丢失了。我想IBM的HttpServletResponse类确实刷新了OutputStream ,但是为Writer使用了一个单独的缓冲区并且没有刷新它。其他应用服务器似乎也这样做了。

因此,如果您将响应数据发送给Writer,那么刷新它会更安全。但是没有必要将OutputStream刷新到讨价还价中。

(我会将此作为评论发布,但缺乏这样做的声誉。)

于 2018-02-12T14:47:41.683 回答
-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.
于 2014-10-14T04:11:36.867 回答