try-with-resource vs java.lang.IllegalStateException:在提交响应后无法调用sendError()

时间:2016-04-01 17:48:00

标签: servlets exception-handling try-with-resources

我的RSS servlet使用try-with-resource为OutputStream out的{​​{1}}及其编写器。在某些情况下,生成RSS文档时会抛出HttpServletResponse,在这种情况下,我需要将HTTP状态500返回给客户端:

SomeException

但是,在调用try (ServletOutputStream out = response.getOutputStream(); OutputStreamWriter writer = new OutputStreamWriter(out, "utf-8")) { response.setContentType("text/xml"); // Generate RSS here } catch (SomeException e) { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); return; } 时,$ out $已经关闭,我说response.sendError()表示响应已经提交(关闭流似乎提交响应自动)。

如果我将IllegalStateExceptionout的初始化移到try-block之外并以finally块(Java7之前的方式)关闭它们,则错误代码将被正确发送。 / p>

我想知道是否有办法继续使用try-with-resource,并且在异常的情况下仍然能够返回错误代码。

谢谢!

1 个答案:

答案 0 :(得分:1)

您不需要关闭您自己没有创建的资源。容器本身创建了底层OutputStream,因此它本身也负责正确关闭它。您应该可视化容器已经在servlet的doXxx()方法周围放置了一个try-with-resources。另请参阅Should I close the servlet outputstream?

不同的是,OutputStream内的doXxx()内的整个资源试用是不必要的。

只是做:

try {
    // Generate RSS here

    OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream(), "UTF-8")) {
    response.setContentType("text/xml");

    // Write RSS here.

} catch (SomeException e) {
    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
}
对于具体问题

无关,如果您将任何已检查的异常重新抛出为ServletException,则容器本身也会自行处理正确的响应代码和消息。

try {
    // ...
} catch (SomeException e) {
    throw new ServletException(e);
}