是否应该在 HttpServletResponse.getOutputStream()/.getWriter() 上调用 .close()?

2022-08-31 10:22:38

在 Java Servlet 中,可以通过 或 访问响应正文。在写信给它之后,是否应该对此进行呼吁?response.getOutputStream()response.getWriter().close()OutputStream

一方面,有布洛奇的劝诫总是关闭s。另一方面,我不认为在这种情况下需要关闭底层资源。套接字的打开/关闭在HTTP级别进行管理,以允许诸如持久连接之类的事情。OutputStream


答案 1

通常,不应关闭流。作为 servlet 请求生命周期的一部分,在 servlet 完成运行后,servlet 容器将自动关闭流。

例如,如果您关闭了流,则在实现过滤器时,该流将不可用。

话虽如此,如果你关闭它,只要你不尝试再次使用它,就不会发生任何不好的事情。

编辑:另一个过滤器链接

EDIT2:adrian.tarau是正确的,如果你想在servlet完成它的事情之后改变响应,你应该创建一个扩展HttpServletResponseWrapper的包装器并缓冲输出。这是为了防止输出直接进入客户端,但也允许您在servlet关闭流时进行保护,如以下摘录所示(强调我的):

修改响应的筛选器通常必须捕获响应,然后才能将其返回到客户端。执行此操作的方法是将生成响应的 servlet 传递给备用流。备用流可防止 servlet 在完成时关闭原始响应流,并允许过滤器修改 servlet 的响应。

从 Sun 的官方文章中可以推断出,从 servlet 关闭 是正常情况,但不是强制性的。OutputStream


答案 2

它们的一般规则是这样的:如果您打开了流,那么您应该将其关闭。如果你没有,你就不应该。确保代码是对称的。

在 的情况下,它不太清晰,因为调用是否是打开流的操作并不明显。Javadoc只是说它“”;类似地用于 .无论哪种方式,显而易见的是“拥有”流/编写器,并且它(或容器)负责再次关闭它。HttpServletResponsegetOutputStream()Returns a ServletOutputStreamgetWriter()HttpServletResponse

因此,要回答您的问题 - 不,在这种情况下,您不应该关闭流。容器必须这样做,如果你在它之前进入那里,你可能会在应用程序中引入微妙的错误。


推荐