德玛西亚99
虽然没有我想的那么清楚,但这是一种工作版本,至少可以为错误页面提供一些自定义。这是第一种方法,但希望可以帮助其他人。处理的异常列表并不广泛,但主要解决 404 错误 ( NoHandlerFoundException) 和其他典型错误,例如InternalServerErrorExceptionand NullPointerException,尝试在最后捕获所有异常,并为所有其他是 a 的错误提供通用错误Exception)。请注意,这不包括与例如 JSTL 模板中的错误语法相关的其他异常(org.apache.jasper.*; 显然无法在此处捕获的异常)。这些是源库的相关更改和添加:CustomSimpleMappingExceptionResolver.java(提供通用异常,但记录详细信息)package ...;import java.util.ArrayList;import java.util.Arrays;import java.util.Date;import javax.ws.rs.InternalServerErrorException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.http.HttpStatus;import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.NoHandlerFoundException;public class CustomSimpleMappingExceptionResolver extends SimpleMappingExceptionResolver { public CustomSimpleMappingExceptionResolver() { // Turn logging on by default setWarnLogCategory(getClass().getName()); } @Override public String buildLogMessage(Exception e, HttpServletRequest req) { return "MVC exception: " + e.getLocalizedMessage(); } @Override protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { // Log exception ex.printStackTrace(); String exceptionCause = ex.toString(); String exceptionType = ex.getClass().getCanonicalName(); // Get the ModelAndView to use ModelAndView mav = super.doResolveException(request, response, handler, ex); // Make more information available to the view - note that SimpleMappingExceptionResolver adds the exception already mav.addObject("url", request.getRequestURL()); mav.addObject("timestamp", new Date()); ArrayList<String> exceptions404 = new ArrayList<String>( Arrays.asList( NoHandlerFoundException.class.getName() ) ); ArrayList<String> exceptions500 = new ArrayList<String>( Arrays.asList( InternalServerErrorException.class.getName(), NullPointerException.class.getName() ) ); String userExceptionDetail = ex.toString(); String errorHuman = ""; String errorTech = ""; if (exceptions404.contains(exceptionType)) { errorHuman = "We cannot find the page you are looking for"; errorTech = "Page not found"; userExceptionDetail = String.format("The page %s cannot be found", request.getRequestURL()); mav.setViewName("/error/404"); mav.addObject("status", HttpStatus.NOT_FOUND.value()); } else if (exceptions500.contains(exceptionType)) { errorHuman = "We cannot currently serve the page you request"; errorTech = "Internal error"; userExceptionDetail = "The current page refuses to load due to an internal error"; mav.setViewName("/error/500"); mav.addObject("status", HttpStatus.INTERNAL_SERVER_ERROR.value()); } else { errorHuman = "We cannot serve the current page"; errorTech = "General error"; userExceptionDetail = "A generic error prevents from serving the page"; mav.setViewName("/error/generic"); mav.addObject("status", response.getStatus()); } Exception userException = new Exception(userExceptionDetail); mav.addObject("error_human", errorHuman); mav.addObject("error_tech", errorTech); mav.addObject("exception", userException); return mav; }}WebAppConfig.java(将自定义异常解析器注册为异常处理程序)package ...;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.PropertySource;import org.springframework.context.annotation.Scope;import org.springframework.context.annotation.ScopedProxyMode;import org.springframework.core.env.Environment;import org.springframework.core.Ordered;import org.springframework.http.HttpStatus;import org.springframework.transaction.annotation.EnableTransactionManagement;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import org.springframework.web.servlet.HandlerExceptionResolver;import org.springframework.web.servlet.NoHandlerFoundException;import org.springframework.web.servlet.view.InternalResourceViewResolver;import java.lang.ClassNotFoundException;import java.lang.NullPointerException;import javax.annotation.Resource;import javax.ws.rs.InternalServerErrorException;import java.util.Properties;@Configuration@ComponentScan("...")@EnableWebMvc@EnableTransactionManagement@PropertySource("classpath:application.properties")public class WebAppConfig extends WebMvcConfigurerAdapter { @Resource private Environment env; // ... @Bean HandlerExceptionResolver customExceptionResolver () { CustomSimpleMappingExceptionResolver resolver = new CustomSimpleMappingExceptionResolver(); Properties mappings = new Properties(); // Mapping Spring internal error NoHandlerFoundException to a view name mappings.setProperty(NoHandlerFoundException.class.getName(), "/error/404"); mappings.setProperty(InternalServerErrorException.class.getName(), "/error/500"); mappings.setProperty(NullPointerException.class.getName(), "/error/500"); mappings.setProperty(ClassNotFoundException.class.getName(), "/error/500"); mappings.setProperty(Exception.class.getName(), "/error/generic"); resolver.setExceptionMappings(mappings); // Set specific HTTP codes resolver.addStatusCode("404", HttpStatus.NOT_FOUND.value()); resolver.addStatusCode("500", HttpStatus.INTERNAL_SERVER_ERROR.value()); resolver.setDefaultErrorView("/error/generic"); resolver.setDefaultStatusCode(200); // This resolver will be processed before the default ones resolver.setOrder(Ordered.HIGHEST_PRECEDENCE); resolver.setExceptionAttribute("exception"); return resolver; } // ... @Bean public InternalResourceViewResolver setupViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views"); resolver.setSuffix(".jsp"); resolver.setExposeContextBeansAsAttributes(true); return resolver; } @Override public void addViewControllers(ViewControllerRegistry registry) { super.addViewControllers(registry); }}Initializer.java(添加dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);;可能不需要)package ...;import org.springframework.web.WebApplicationInitializer;import org.springframework.web.context.ContextLoaderListener;import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;import org.springframework.web.servlet.DispatcherServlet;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRegistration;public class Initializer implements WebApplicationInitializer { public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(WebAppConfig.class); servletContext.addListener(new ContextLoaderListener(ctx)); ctx.setServletContext(servletContext); DispatcherServlet dispatcherServlet = new DispatcherServlet(ctx); dispatcherServlet.setThrowExceptionIfNoHandlerFound(true); // Add the dispatcher servlet mapping manually and make it initialize automatically ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", dispatcherServlet); servlet.addMapping("/"); servlet.addMapping("*.png"); servlet.addMapping("*.jpg"); servlet.addMapping("*.css"); servlet.addMapping("*.js"); servlet.addMapping("*.txt"); servlet.setLoadOnStartup(1); // ... }}与错误类相关的视图和标签的结构: src/main/webapp/WEB-INF/ ├── tags │ └── error.tag └── views ├── error │ ├── 404.jsp │ ├── 500.jsp └────── generic.jspsrc/main/webapp/WEB-INF/tags/error.tag<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><!DOCTYPE html><head> <title>Error page</title></head><body><div class="container"> <h3><c:out value="${error_human}" /></h3> <p><br/><br/></p> <div class="panel panel-primary"> <div class="panel-heading"> <c:out value="${error_tech}" /> </div> <div class="panel-body"> <p><c:out value="${exception_message}" /></p> </div> </div></div></body></html>src/main/webapp/WEB-INF/views/error/404.jsp<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" isErrorPage="true" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ taglib tagdir="/WEB-INF/tags/" prefix="g" %><c:set var = "error_human" scope = "session" value = "We cannot find the page you are looking for"/><c:set var = "error_tech" scope = "session" value = "Page not found"/><c:set var = "exception_message" scope = "session" value = "The current page cannot be found"/><g:error />src/main/webapp/WEB-INF/views/error/500.jsp<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" isErrorPage="true" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ taglib tagdir="/WEB-INF/tags/" prefix="g" %><c:set var = "error_human" scope = "session" value = "We cannot currently serve the page you request"/><c:set var = "error_tech" scope = "session" value = "Internal error"/><c:set var = "exception_message" scope = "session" value = "The current page refuses to load due to an internal error"/><g:error />src/main/webapp/WEB-INF/views/error/generic.jsp<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" isErrorPage="true" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ taglib tagdir="/WEB-INF/tags/" prefix="g" %><c:set var = "error_human" scope = "session" value = "We cannot serve the current page"/><c:set var = "error_tech" scope = "session" value = "General error"/><c:set var = "exception_message" scope = "session" value = "A generic error prevents from serving the page"/><g:error />