java - 在 Spring 4 中定义异常处理程序以返回自定义 404 和 500 页面

标签 java spring spring-mvc thymeleaf

我的目的是为我的所有 Controller 定义一个全局自定义 404 页面,并为所有异常定义一个全局 500 页面。 我在这里阅读了一堆问题以及来自 Google 第一个结果页面的所有文章。

我有一个 WebInitializer:

public class MyWebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) throws ServletException {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
          rootContext.register(WebAppConfiguration.class);
          AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
        DispatcherServlet servlet = new DispatcherServlet(dispatcherContext);
        servlet.setThrowExceptionIfNoHandlerFound(true);
        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", servlet);
          dispatcher.setLoadOnStartup(1);
          dispatcher.addMapping("/");
    }
}

现在我有以下异常处理程序:

    @ControllerAdvice
    public class CustomGlogalExceptionHandler {
    public static final String DEFAULT_ERROR_VIEW = "/error/500";

    @ExceptionHandler(value = Exception.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
        if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null)
            throw e;
        ModelAndView mav = new ModelAndView();
        mav.addObject("url", req.getRequestURL());
        mav.setViewName(DEFAULT_ERROR_VIEW);
        return mav;
    }

    @ExceptionHandler(value = NoHandlerFoundException.class)
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    public ModelAndView noPageFoundHandler(HttpServletRequest req, Exception e) throws Exception {
        ModelAndView mav = new ModelAndView();
        mav.addObject("url", req.getRequestURL());
        mav.setViewName("/error/404");
        return mav;
    }
}

点击 http://localhost:8080/test 效果很好:我得到了 404 自定义页面 + 响应代码 404。 如果我人为地将其扔到某个地方,它也可以正常工作:它显示我的 500 自定义页面 + 响应代码 500。

但如果发生一些真正的异常,我既不会得到 500 响应代码,也不会得到我的自定义 500 页面。 例如,现在我有 org.hibernate.LazyInitializationException ,但我在 Chrome 控制台中看到的只是 200 个响应代码,尽管我在服务器控制台中看到了完整的堆栈跟踪,并且异常是它显示的最后一个。 此外,如果 Thymeleaf 模板引擎抛出异常,它会在浏览器中显示完整的堆栈跟踪。 我还应该配置什么才能使其正常工作? 谢谢。

最佳答案

spring 不会拾取你的可抛出类。 [ExceptionHandlerExceptionResolver][1] 需要异常或其子类型。
应该是这样

@ExceptionHandler(value = Excepton.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)

因此,无论您的注释被重新抛出并处理到 500,休息都会在没有 Spring 通知的情况下进行

 if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null)
            throw e;

或者。

其他选项是使用 SimpleMappingExceptionResolver,只需声明它

<bean id="simpleMappingExceptionResolver" class=
     "org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
      <map>
         <entry key="Exception" value="gen_error"/>

      </map>
    </property>

    <!-- See note below on how this interacts with Spring Boot -->
    <property name="defaultErrorView" value="error"/>
    <property name="exceptionAttribute" value="ex"/>

    <!-- Name of logger to use to log exceptions. Unset by default, 
           so logging is disabled unless you set a value. -->
    <property name="warnLogCategory" value="example.MvcLogger"/>
  </bean>

= bean

@Bean
public SimpleMappingExceptionResolver exceptionResolver() {
    SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();

    Properties exceptionMappings = new Properties();

    exceptionMappings.put("java.lang.Exception", "error/error");
    exceptionMappings.put("java.lang.RuntimeException", "error/error");

    exceptionResolver.setExceptionMappings(exceptionMappings);



    return exceptionResolver;
}

关于java - 在 Spring 4 中定义异常处理程序以返回自定义 404 和 500 页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40210733/

相关文章:

java - BlowFish 解密 - nCFB 模式

java - 在java代码中使用savedInstanceState来保存可重用的值

java - 在Java中加载和显示HTML+CSS

spring - 将 Spring Web MVC 应用程序部署为域根中的网站

spring-mvc - 获取mybatis中插入记录的自动生成的key

java - RequestFactory 没有填充我的实体代理的所有字段

java - Spring - AWS(无 Spring Boot): java. lang.IllegalArgumentException:不是托管类型

java - Spring 形式 :select cats as toString

java - 使用 Java 中的 RESTful API,生成工件。

javascript - Azure 单点登录发布请求时出现 403 禁止错误