我发现了another post,展示了如何创建我们自己的检查异常,这些异常还返回与500不同的HTTP代码。然而,我需要它是一个RuntimeException。然后,我发现WebApplicationException是一个未经检查的异常,它返回一个HTTP代码,但不允许我像常规异常那样设置消息。
Java 6中是否有任何未经检查的异常,允许我设置一个错误消息,就像在常规异常中一样,并且还可以返回我可以设置的HTTP状态代码?
编辑:,包括解释为什么我要这样做,这是约翰的要求。
我创建了一个过滤器来捕获来自请求参数的HTML和XSS攻击。我没有每次在Filter.doFilter中检查这个太慢,而是扩展了HttpServletRequestWrapper,并像这样使用它。
HttpFilterRequest implements Filter
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
chain.doFilter(new SafeHttpRequest((HttpServletRequest) request), response);
} catch (SecurityViolationException e) {
log.warn(format("A security violation was detected. Please enable debug for further details: %s]", e.getMessage()));
HttpServletResponse resp = (HttpServletResponse) response;
resp.sendError(e.getStatusCode());
}response);
}
SafeHttpRequest extends HttpServletRequestWrapper (supressing parts to shorten code)
@Override
public String getParameter(String parameter) {
return xssAndHtmlValidation(super.getParameter(parameter));
}
@Override
public String getHeader(String name) {
return xssAndHtmlValidation(super.getHeader(name));
}xssAndHtmlValidation()抛出SecurityViolationException,这是一个RuntimeException,但是doFilter的catch块不能工作,因为我的异常是作为包含SecurityViolationException的ServletException抛出的。
发布于 2015-10-07 21:38:11
好的,所以问题是您希望SafeHttpRequest.xssAndHtmlValidation()抛出一个可以通过HttpServletRequest.getParameter()和HttpServletRequest.getHeader()传递的异常,这两个异常都不声明任何检查的异常。您希望这个异常最终被HttpFilterRequest.doFilter()捕获。您希望它具有可自定义的消息,并且希望它携带HTTP响应代码。
显然,您需要一个未经检查的异常才能以这种方式处理问题。通过扩展java.lang.RuntimeException,从头开始创建一个新的系统似乎是最合适的。您可以为该类提供任何您想要的字段、构造函数和方法,通过它们将任何信息从xssAndHtmlValidation()传输到过滤器。为异常类这样做与对任何其他类这样做没有什么不同,尽管构造函数应该确保调用适当的超类构造函数。
然后,筛选器必须具有新的自定义异常类型的catch块。由于它是您自己的自定义异常,它不太可能被请求和筛选器之间的任何东西捕获,而且由于您将捕获该特定异常,您可以轻松地调用您为自己提供的任何好方法,比如getResponseCode()。据推测,catch块随后将调用响应对象上的一个sendError()方法,然后正常返回,而不是向堆栈中抛出异常。
顺便指出,如果问题检测得太晚了,在底层资源已经提交了不同的响应之后,那么尝试sendError()将导致IllegalStateException,而不是更改响应代码。客户端不会看到这一点(因为响应已经提交了),但是响应可能被截断。
还请注意,不清楚是否确实需要您的自定义异常来携带HTTP响应代码。它会因不同的情况而有所不同吗?如果没有,那么适当的响应代码是在异常被抛出这一事实中固有的,并且过滤器可以仅仅基于它捕获了特定的异常类型这一事实而适当地设置响应代码。
更新:
当然,如果您的JSP引擎要包装您的异常并将其作为ServletException抛出,那么您可以捕获该异常并根据exception.getCause().getClass()决定要做什么(但是要注意导致null的原因)。如果引擎还没有在这种情况下提交响应,这就可以工作。
如果您的JSP引擎最终要拦截所有异常并将它们转换为HTTP代码500响应,那么任何基于抛出异常的方法都是死胡同。您最好的选择是在前端,在过滤器中处理它,然后再将请求传递到链中。这是一种天生的过滤器。
您表示担心在筛选器中进行测试可能太慢,但只有在请求包含从未被下游组件检查过的参数或标头的情况下,才可能比建议的替代方案慢。另一方面,如果请求头或参数被访问超过一次,则基于请求包装器的方法实际上可能是较慢的方法,因为您将对每个访问执行验证,即使每个参数/头只需要执行一次。
https://stackoverflow.com/questions/33001410
复制相似问题