我们希望实施“fault barrier”策略来管理应用程序中的异常。我们的应用程序有一个问题是“回传”响应的概念,基本上是无操作,我们希望返回优先投掷500,400等HTTP状态代码 - 例如我们面向外部的应用程序应始终返回有效的响应,即使引发了基础异常 - 我们希望处理应用程序的内部,并仍然返回有效的noop响应。
我们的第一个实现是一个Servlet过滤器,它将把所有请求包装在try / catch块中,并返回catch的默认返回值,例如:
try{
chain.doFilter()
} catch (Throwable t) {
generatePassbackResponse(HttpServletRequest req, HttpServletResponse res)
}
虽然这主要起作用,并且感觉很好而且干净(我们可以返回漂亮的文本,适当地设置内容/类型等),但是一个问题似乎是当抛出异常时,响应仍然通过状态 - 代码:500。
HttpServletResponse.setStatus(200)没有效果,javadoc确实说它只适用于普通请求。
我们的第二个实现思路是我们可能必须转发到另一个页面,或者将errorPage插入到web.xml中并手动将errorError发送到该页面 - 尽管我们对是否有人有特定推荐感兴趣。
答案 0 :(得分:2)
有两种方法可以设置响应的HTTP状态:
<error-page>
机制sendError 的Javadoc表示在调用 sendError 后应该认为响应已经提交(这可以解释您的应用服务器的行为)。
实施自定义HttpServletResponseWrapper
可以强制执行您的行为
需要 sendError (并且可能在内存中缓冲整个请求,以便您可以为通常提交请求之后发生的异常发送“回传”。)
答案 1 :(得分:1)
如果我没记错的话,如果您不想要其他任何东西来处理请求,则不应该调用chain.doFilter()。过滤器将在每种情况下执行,但chain.doFilter()将确保调用所有其他过滤器。为了正确阻止异常访问用户,您需要停止请求/响应处理。
您可以使用类似Spring及其拦截器的框架(就像过滤器一样)采用不同的路径。 Spring为您提供了对Interceptor的大量控制以及如何处理响应。当然,这对你的问题有点重要。
根据评论,http://java.sun.com/products/servlet/Filters.html:
最重要的方法 过滤器接口是doFilter 方法...此方法通常执行 以下某些操作:
如果当前过滤器是最后一个 以链接结束的链中的过滤器 目标servlet,下一个实体是 链末端的资源; 否则,它是下一个过滤器 在WAR中配置。它调用 通过调用下一个实体 链对象上的doFilter方法 (传递请求和回复 它被称为或被包裹 它可能已创建的版本)。 或者,它可以选择阻止 通过不拨打电话的请求 调用下一个实体。在后者 情况下,过滤器负责 填写答复。
这个想法是这个“故障障碍”需要阻止所有其他过滤器执行,并且只是以它认为必要的方式处理请求/响应。
答案 2 :(得分:0)
你能不能只使用标准的web.xml配置:
<error-page>
<error-code>500</error-code>
<location>/error.jsp</location>
</error-page>
<error-page>
<location>/error.jsp</location>
<exception-type>java.lang.Exception</exception-type>
</error-page>
我无法看到你还想尝试做什么,而这还不适合?如果它只是错误代码,那么我认为你可以使用响应对象来设置它。
答案 3 :(得分:0)
RESTEasy框架允许您使用ExceptionMappers选择响应代码。可能你不愿意使用它,但我发现它非常快速有效。
包含ExceptionMappers的JBoss文档 http://docs.jboss.org/resteasy/docs/2.0.0.GA/userguide/html_single/index.html#ExceptionMappers
我的博客文章显示了一个通用RESTEasy代码片段 http://gary-rowe.com/agilestack/2010/08/22/my-current-development-stack/