如何处理生成图像的Servlet中的异常?

时间:2010-05-17 18:42:08

标签: java jsp servlets

我有一个简单的(Servlet,JSP和JSTL)Web应用程序,其主要功能是显示从后端服务器检索的图像。控制器servlet将用户转发到JSP,JSP又使用另一个Servlet在同一个JSP上显示生成的图像。更进一步说,JSP有一行类似于:

<a href="<c:out value='${imageURL}'/>"><img src="<c:out value='${imageURL}'/>" alt="image view" border="1"></a>

在图像生成servlet上调用GET请求,使其生成图像。

我的问题是:如何处理这个图像生成servlet抛出的异常?

我已经定义了一个错误页面(在web.xml中)来处理我的Web应用程序中的ServletException,但这不适用于这个生成图像的Servlet,并导致我的Tomcat服务器日志中出现以下错误:

SEVERE: Exception Processing ErrorPage[exceptionType=javax.servlet.ServletException, location=/WEB-INF/ExceptionPage.jsp]
java.lang.IllegalStateException: Cannot reset buffer after response has been committed

在这种情况下我的追索权是什么?

我希望能够处理从这个生成图像的Servlet抛出的异常,并在主UI上显示一些错误或将用户转发到另一个错误页面。

5 个答案:

答案 0 :(得分:3)

您无法更改响应以重定向到错误页,而发送回复。现在改变整个响应已经太晚了。您无法从客户端请求已经发送的字节。这就是IllegalStateException代表的地方。这是一个不归路的点。

最好的做法是只记录异常,或重写代码,以便在业务逻辑尚未完成任务时不向响应写入任何位(也不设置响应头)然而。一旦确定业务逻辑没有抛出任何异常,就开始编写(从而间接地提交)响应。如果业务逻辑在尚未触及响应的情况下抛出异常,那么您可以安全地将其抛出,以使其最终出现在错误页面中。虽然在图像servlet的情况下,您可能还希望将一些标准404.gif流式传输到响应中。这是因为您无法在<img>元素中显示另一个HTML(错误)页面,并且您也无法更改父JSP / HTML页面的URL,因为这涉及不同的请求。

答案 1 :(得分:1)

根据servlet API,没有servlet应该在同一个响应对象上调用getWriter()和getOutputStream(),因为它会导致IllegalStateException。通常这是此异常的来源。如果要输出二进制数据和图像文件,则应使用getOutputStream()。

答案 2 :(得分:1)

看起来你遇到的问题是你的ExceptionPage.jsp,而不是你的servlet代码。

这个

  

java.lang.IllegalStateException:   响应后无法重置缓冲区   已经承诺

表示您已尝试发送回复。 您可能直接打开了输出流并向其写入了一些数据。一旦你完成它,你就不能尝试在响应上设置标题等(它们已经在去客户端的路上)。

你需要做一个更好的状态管理。最好的方法是将请求预处理与响应生成分开。一旦你写回复,你只能做或死。为此,请检查您是否从响应输出中捕获IOExceptions,将它们包装到ServletException并将它们重定向到您的错误页面。你真的无法在当前请求的上下文中处理它们。

答案 3 :(得分:0)

首先,确定抛出非法国家例外的原因。

可能只是想修复你的代码,而不是处理抛出的异常

答案 4 :(得分:0)

您应该捕获异常并使用RequestDispatcher将请求转发到所需的页面:

  public void doGet(HttpServletRequest request, 
                HttpServletResponse response) 
throws ServletException, IOException  {

// The following piece of code results in NumberFormatException which will
// be detected by the container. The RequestDispatcher object will forward
// the same request to the other resource, here the file: forwardedJSP.jsp 
try  {
  int test = Integer.parseInt("abc");
} catch (NumberFormatException nfe) {
    RequestDispatcher rd = request.getRequestDispatcher("/forwardedJSP.jsp"); 
    rd.forward(request, response); 
}}