我的目的是为所有控制器定义一个全局自定义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模板引擎抛出,它会在浏览器中显示完整的堆栈跟踪。
我还应该配置什么才能使其正常工作?
感谢。
答案 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;
}