我的目的是为我的所有 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/