Springboot自定义错误页面(4xx/5xx)及异常集中处理

  • 自定义异常页面(4xx,5xx)
  • Controller异常集中处理

自定义异常页面(4xx,5xx)

  • Springboot 1.4.0 版本以下
    自定义一个实现EmbeddedServletContainerCustomizer接口的Component,在该实例中进行自定义ErrorPage配置。
    示例代码如下:
@Component
public class CustomizationBean implements EmbeddedServletContainerCustomizer {
    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        Set errorPages = new HashSet<>();
        errorPages.add(new ErrorPage(HttpStatus.NOT_FOUND, "/error/404"));
        errorPages.add(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500"));
        errorPages.add(new ErrorPage(Throwable.class, "/error/500"));
        container.setErrorPages(errorPages);
    }
}
  • Springboot 1.4.0 版本以上
    通过实现ErrorPageRegistrar接口定义错误页面,该方式定义的错误页面等价于传统项目中在web.xml中配置的error-page。
    示例如下:
 @Component
public class ErrorConfiguration implements ErrorPageRegistrar {

    @Override
    public void registerErrorPages(ErrorPageRegistry registry) {
        ErrorPage[] errorPages = new ErrorPage[]{
                new ErrorPage(HttpStatus.NOT_FOUND, "/error/404"),
                new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500"),
                new ErrorPage(Throwable.class, "/error/500")
        };
        registry.addErrorPages(errorPages);
    }
}

ErrorPage通过HttpStatus或者Throwable 以及自定义的一个错误展示路径,发生对应的错误时通过forward的方式请求指定的path。

PS:ErrorPageRegistrar,ErrorPageRegistry,ErrorPage在springboot 2.0.0版本更新后变更了包路径,2.0.0以前的包路径为:org.springframework.boot.web.servlet,2.0.0更新后变更为:org.springframework.boot.web.server

Controller异常集中处理

Controller的异常集中处理可以通过定义一个ControllerAdvice来处理,配合@ExceptionHandler指定针对不同异常做不同处理。
示例如下:

@ControllerAdvice
public class GlobalExceptionHandler {
    private Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    /**
     * 捕获具体指定外的所有异常
     *
     * @param ex
     * @param request
     * @param response
     */
    @ExceptionHandler(value = Exception.class)
    private void handle(Exception ex, HttpServletRequest request, HttpServletResponse response) {
        LOGGER.error("***** GlobalException Handle Start *****");
        LOGGER.error("Exception:{}", ex.toString());
        LOGGER.error("Message:{}", ex.getMessage());
        LOGGER.error("Request Url:{}", request.getRequestURL());
        Enumeration enumeration = request.getParameterNames();
        LOGGER.error("Parameters:");
        while (enumeration.hasMoreElements()) {
            String name = enumeration.nextElement().toString();
            LOGGER.error("[{}]:[{}]", name, request.getParameter(name));
        }
        StackTraceElement[] error = ex.getStackTrace();
        LOGGER.error("StackTrace:");
        for (StackTraceElement stackTraceElement : error) {
            LOGGER.error("{}", stackTraceElement.toString());
        }
        LOGGER.error("***** GlobalException Handle End *****");
    }


}

@ExceptionHandler注解定义

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
    Class[] value() default {};
}

该示例代码指定的异常为Exception.class,即表示所有Exception及子类异常都可以处理,通过查看@ExceptionHandler注解我们可以知道该注解支持Throwable的所有子类,包括ExceptionError,并且可以同时指定多个异常或错误。

你可能感兴趣的:(Java)