2

继续线程: Apache Tiles 和 Spring MVC 中的全局异常页面

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

<error-page>
    <error-code>404</error-code>
    <location>/WEB-INF/jsp/404.jsp</location>
</error-page>

我注意到 Spring MVC 中的另一个问题:

a) 如果没有 @RequestMapping匹配,那么确实会打印我的自定义错误 jsp。

b) 如果 a@RequestMapping匹配,但该方法设置错误状态,例如。

response.setStatus(404);

然后选择Tomcat的(7.0.29)默认错误页面,而不是我的jsp。

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

4

3 回答 3

5

我认为您遇到的情况是由您提到的线路引起的:response.setStatus(404);

该方法不会触发容器的错误页面机制,应该在没有错误的情况下使用。要触发该机制,您必须使用官方文档中推荐的sendError 。

顺便说一句,我刚刚发现 Servlet Spec 的行为有所不同。2.3 和 2.4(在这里阅读)。在 2.3 中,这两种方法被称为做同样的事情,而在 2.4 中它们不同......

于 2013-06-03T17:07:18.267 回答
0

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

看看这个教程:http ://doanduyhai.wordpress.com/2012/05/06/spring-mvc-part-v-exception-handling/

于 2013-06-03T09:35:17.487 回答
0

你可能想看看ExceptionHandler

它非常好用且灵活,允许您实现逻辑以显示不同的错误页面并根据异常输出不同的 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 表示验证错误,等等),并将该代码与您的错误页面一起返回。

于 2013-06-03T10:12:02.377 回答