首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@ExceptionHandler + @ResponseStatus

@ExceptionHandler + @ResponseStatus
EN

Stack Overflow用户
提问于 2013-12-05 17:00:20
回答 2查看 3.3K关注 0票数 3

我正在使用以下代码处理我的受控异常:

代码语言:javascript
复制
  @ExceptionHandler(MyException.class)
       @ResponseStatus(HttpStatus.NOT_FOUND)
       public ModelAndView handleMyException(MyException e) {
          ModelAndView mav = new ModelAndView(ERROR_PAGE);
          (...)
          return mav;
       }

也就是说,我希望对不同的错误使用自定义视图,并对HTTP响应使用响应状态代码。

同时,对于纯404,我在web.xml中有以下配置

代码语言:javascript
复制
<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的方法,也就是显示的视图。

另外,如果我抛出一个不同的响应代码,我会得到异常的默认行为,而不是我的自定义视图。

EN

回答 2

Stack Overflow用户

发布于 2013-12-08 18:51:07

我不能用Tomcat6和Spring2.3.4重现你的问题。这是正确的,因为根据Servlet规范2.5,部署描述符定义了一个错误页面描述列表。当servlet或过滤器对特定状态代码(...)的响应调用sendError时,该语法允许容器返回资源的配置

我跟踪了Spring基于@ResponseStatus(HttpStatus.NOT_FOUND)设置响应代码的位置,如下所示:

代码语言:javascript
复制
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);
    }

在我的例子中,如果错误处理程序方法被注释

代码语言:javascript
复制
 @ResponseStatus(HttpStatus.NOT_FOUND)

选择以下分支:

代码语言:javascript
复制
else {
        webRequest.getResponse().setStatus(this.responseStatus.value());
    }

因为调用了HttpServletResponse.setStatus而不是HttpServletResponse.sendError,web容器忽略了在<error-code>404</error-code>中定义的错误页

我希望我的解释对你自己跟踪这个问题是有用的。我怀疑某个地方调用了HttpServletResponse.sendError,它会触发web容器返回默认错误页面

票数 3
EN

Stack Overflow用户

发布于 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请求。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20395539

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档