问题
我用谷歌搜索来找不到权威的答案。在Java servlet中,可以通过response.getOutputStream()或response.getWriter()访问响应主体。应该在写入之后在此流上调用.close()吗?
一方面,Blochian劝告总是关闭输出流。另一方面,我认为在这种情况下不存在需要关闭的底层资源。套接字的打开/关闭在HTTP级别进行管理,以允许诸如持久连接之类的事情。
#1 热门回答(81 赞)
通常你不应该关闭流。作为servlet请求生命周期的一部分,servlet完成运行后,servlet容器将自动关闭流。
例如,如果你关闭了流,则在实施aFilter时将无法使用该流。
说了这么多,如果你关闭它,只要你不再尝试使用它就不会发生任何不好的事情。
EDIT2:adrian.tarau是正确的,因为如果你想在servlet完成它之后改变响应,你应该创建一个包装器来扩展HttpServletResponseWrapper并缓冲输出。这是为了防止输出直接进入客户端,但是如果servlet关闭了流,也可以保护输出,如本节摘录(强调我的):
修改响应的过滤器通常必须在响应返回到客户端之前捕获响应。执行此操作的方法是将生成响应的servlet传递给替代流。备用流阻止servlet在完成时关闭原始响应流,并允许过滤器修改servlet的响应。
Article
从Sun官方文章中可以推断出,从servlet关闭输出流是正常现象,但不是强制性的。
#2 热门回答(59 赞)
它们的一般规则是:如果你打开流,那么你应该关闭它。如果你没有,你不应该。确保代码是对称的。
在HttpServletResponse的情况下,它有点不那么明确,因为如果调用getOutputStream()是一个打开流的操作则不明显。 Javadoc只是说它是"Returns a ServletOutputStream";同样为getWriter()。无论哪种方式,很清楚的是,HttpServletResponse"拥有"流/编写器,它(或容器)负责再次关闭它。
所以回答你的问题 - 不,你不应该在这种情况下关闭流。容器必须这样做,如果你在它之前进入,你可能会在应用程序中引入微妙的错误。
#3 热门回答(4 赞)
如果有可能在"包含"资源上调用过滤器,则绝对不应该关闭流。这将导致包含资源因"流关闭"异常而失败。
在Java Servlet中,是否需要调用response.getOutputStream()或response.getWriter().close()一直是讨论的焦点。虽然Blochian建议总是关闭输出流,但在实际场景中,由于servlet容器会自动关闭流,因此通常不需要显式关闭。关闭流可能会导致在过滤器中出现问题,或者在包含资源时引起异常。然而,特殊情况如需要修改响应时,可能需要创建响应包装器并缓冲输出,这时关闭流是有意义的。
4273

被折叠的 条评论
为什么被折叠?



