我正在使用以下代码处理我的受控异常:
@ExceptionHandler(MyException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ModelAndView handleMyException(MyException e) {
ModelAndView mav = new ModelAndView(ERROR_PAGE);
(...)
return mav;
}也就是说,我希望对不同的错误使用自定义视图,并对HTTP响应使用响应状态代码。
同时,对于纯404,我在web.xml中有以下配置
<error-page>
<error-code>404</error-code>
<location>/404</location>
</error-page>
<error-page>
<error-code>400</error-code>
<location>/400</location>
</error-page>这将带到404特定视图。
问题是,当从我的@ExceptionHandled方法抛出一个NOT_FOUND时,它不会显示我的自定义视图,调试显示执行实际上是通过handleMyException方法执行的,但在执行完成后,它还会通过映射web.xml中的/404的方法,也就是显示的视图。
另外,如果我抛出一个不同的响应代码,我会得到异常的默认行为,而不是我的自定义视图。
发布于 2013-12-08 18:51:07
我不能用Tomcat6和Spring2.3.4重现你的问题。这是正确的,因为根据Servlet规范2.5,部署描述符定义了一个错误页面描述列表。当servlet或过滤器对特定状态代码(...)的响应调用sendError时,该语法允许容器返回资源的配置
我跟踪了Spring基于@ResponseStatus(HttpStatus.NOT_FOUND)设置响应代码的位置,如下所示:
public class ServletInvocableHandlerMethod (...)
private void setResponseStatus(ServletWebRequest webRequest) throws IOException {
if (this.responseStatus == null) {
return;
}
if (StringUtils.hasText(this.responseReason)) {
webRequest.getResponse().sendError(this.responseStatus.value(), this.responseReason);
}
else {
webRequest.getResponse().setStatus(this.responseStatus.value());
}
// to be picked up by the RedirectView
webRequest.getRequest().setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, this.responseStatus);
}在我的例子中,如果错误处理程序方法被注释
@ResponseStatus(HttpStatus.NOT_FOUND)选择以下分支:
else {
webRequest.getResponse().setStatus(this.responseStatus.value());
}因为调用了HttpServletResponse.setStatus而不是HttpServletResponse.sendError,web容器忽略了在<error-code>404</error-code>中定义的错误页
我希望我的解释对你自己跟踪这个问题是有用的。我怀疑某个地方调用了HttpServletResponse.sendError,它会触发web容器返回默认错误页面
发布于 2013-12-06 04:30:44
听起来问题可能是web容器试图处理400/404从web应用程序中看到的错误(因为它不理解这些错误的上下文)。您可能需要删除web.xml错误页面定义,并向Spring控制器添加更多配置来处理一般的400/404错误。
当我在我的应用程序中设置异常处理时,这个指南对我帮助很大:http://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
web.xml告诉应用程序容器如何处理应用程序生成的各种响应代码。当您从控制器方法中获得异常时,它将由带有Spring @ExceptionHandler注释的方法处理。在这一点上,应用程序容器没有参与,所以它还不知道发生了什么。
我最好的理解是,当你从异常处理方法生成一个404Http状态并返回时,Spring在这一点上基本上完成了,应用容器返回并说:“我得到了一个404,我用一个404做什么?啊,重定向到/404”。然后,控制权回到web应用程序本身来处理/404请求。
https://stackoverflow.com/questions/20395539
复制相似问题