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

时间:2016-10-24 04:33:03

标签: java spring spring-mvc thymeleaf

我的目的是为所有控制器定义一个全局自定义404页面,为所有例外定义一个全局500页面。 我在这里阅读了一堆问题+谷歌第一个结果页面上的所有文章。

我有一个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模板引擎抛出,它会在浏览器中显示完整的堆栈跟踪。 我还应该配置什么才能使其正常工作? 感谢。

1 个答案:

答案 0 :(得分:1)

春天不会接你的可抛出的班级。 [ExceptionHandlerExceptionResolver][1]期望例外或其子类型 所以应该

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

因此无论您注释的是什么,都要重新投入并处理为500,其余的没有春天的通知

 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;
}