Java Spring MVC未选择全局异常页面

Java Spring MVC未选择全局异常页面,java,jakarta-ee,tomcat,servlets,spring-mvc,Java,Jakarta Ee,Tomcat,Servlets,Spring Mvc,继续线程: 我的web.xml中定义了一个错误页面: <error-page> <error-code>404</error-code> <location>/WEB-INF/jsp/404.jsp</location> </error-page> 然后选择Tomcat的(7.0.29)默认错误页面,而不是我的jsp 为什么?如何始终显示我的404页面?使用spring MVC时,最好使用内置异常处理程序向

继续线程:

我的web.xml中定义了一个错误页面:

<error-page>
    <error-code>404</error-code>
    <location>/WEB-INF/jsp/404.jsp</location>
</error-page>
然后选择Tomcat的(7.0.29)默认错误页面,而不是我的jsp


为什么?如何始终显示我的404页面?

使用spring MVC时,最好使用内置异常处理程序向用户显示错误页面


看看本教程:

您可能想看看

它非常好而且灵活,允许您实现逻辑来显示不同的错误页面,并根据异常输出不同的HTTP响应代码(这并不总是一个要求,但很高兴知道您可以轻松做到这一点)

我将我的代码粘贴在这里,因为我认为它对于解决与此主题相关的常见问题非常有用

@ExceptionHandler(Exception.class)
public ModelAndView resolveException(Exception ex,
                                     HttpServletRequest request,
                                     HttpServletResponse response) {

    // I get an email if something goes wrong so that I can react.
    if (enableEmailErrorReporting)
        sendExceptionEmail(request.getRequestURL().toString(), ex);

    ModelAndView mav = getModelAndView(ex, request);

    setStatusCode(ex, response);

    return mav;

}

protected ModelAndView getModelAndView(Exception ex,
                                       HttpServletRequest request) {
    // Here you can implement custom logic to retrieve the correct
    // error page depending on the exception. You should extract
    // error page paths as properties or costants.
    return new ModelAndView("/WEB-INF/app/error.html");
}

// This is really nice.
// Exceptions can have status codes with the [`ResponseStatus`][2] annotation.
private void setStatusCode(Exception ex, HttpServletResponse response) {

    HttpStatus statusCode = HttpStatus.BAD_REQUEST;

    ResponseStatus responseStatus =
            AnnotationUtils.findAnnotation(ex.getClass(),
                                           ResponseStatus.class);

    if (responseStatus != null)
        statusCode = responseStatus.value();

    response.setStatus(statusCode.value());

}

这里的逻辑是控制器方法抛出未修补的异常。Spring将调用标记为
ExceptionHandler
的方法(每个控制器、每个异常或全局默认值都可以有一个,通常我让我的所有控制器都从定义此方法的
BaseController
类继承)。传递给该方法的是异常本身以及选择要显示的正确视图所需的任何其他信息。更重要的是,您可以查看是否在异常上声明了特定的HTTP响应代码(例如,500表示未检查的异常,400表示验证错误等),并将该代码与错误页一起返回。

我认为您遇到的问题是由您提到的行引起的:
response.setStatus(404)

此方法不会触发容器的错误页面机制,应该在没有错误时使用。要触发该机制,您必须使用,这是官方文件中建议的

顺便说一句,我刚刚发现Servlet规范2.3和2.4的行为有所不同
(). 在2.3中,这两种方法被认为是做同样的事情,而在2.4中,它们是不同的………

您需要编写请求拦截器来处理异常。但这不是异常。我只是设置了一个响应状态。我使用一个处理程序来处理未捕获的
可丢弃文件
,但事实并非如此:我需要处理一个404(来自未解析的映射和一些设置状态的代码)。在3个小时试图理解为什么我的错误页面被Tomcat覆盖后,我尝试了你的解决方案。。就这样。发送状态就解决了问题。这太疯狂了,框架在那里没有发挥作用。
@ExceptionHandler(Exception.class)
public ModelAndView resolveException(Exception ex,
                                     HttpServletRequest request,
                                     HttpServletResponse response) {

    // I get an email if something goes wrong so that I can react.
    if (enableEmailErrorReporting)
        sendExceptionEmail(request.getRequestURL().toString(), ex);

    ModelAndView mav = getModelAndView(ex, request);

    setStatusCode(ex, response);

    return mav;

}

protected ModelAndView getModelAndView(Exception ex,
                                       HttpServletRequest request) {
    // Here you can implement custom logic to retrieve the correct
    // error page depending on the exception. You should extract
    // error page paths as properties or costants.
    return new ModelAndView("/WEB-INF/app/error.html");
}

// This is really nice.
// Exceptions can have status codes with the [`ResponseStatus`][2] annotation.
private void setStatusCode(Exception ex, HttpServletResponse response) {

    HttpStatus statusCode = HttpStatus.BAD_REQUEST;

    ResponseStatus responseStatus =
            AnnotationUtils.findAnnotation(ex.getClass(),
                                           ResponseStatus.class);

    if (responseStatus != null)
        statusCode = responseStatus.value();

    response.setStatus(statusCode.value());

}