SpringBoot中的全局异常处理

SpringBoot中的全局异常处理 本篇要点

介绍SpringBoot默认的异常处理机制。

如何定义错误页面。

如何自定义异常数据。

如何自定义视图解析。

介绍@ControllerAdvice注解处理异常。

一、SpringBoot默认的异常处理机制

默认情况下,SpringBoot为以下两种情况提供了不同的响应方式:

Browser Clients浏览器客户端:通常情况下请求头中的Accept会包含text/html,如果未定义/error的请求处理,就会出现如下html页面:Whitelabel Error Page,关于error页面的定制,接下来会详细介绍。

SpringBoot中的全局异常处理

Machine Clients机器客户端:Ajax请求,返回ResponseEntity实体json字符串信息。

{ "timestamp": "2020-10-30T15:01:17.353+00:00", "status": 500, "error": "Internal Server Error", "trace": "java.lang.ArithmeticException: / by zero...", "message": "/ by zero", "path": "http://www.likecs.com/" }

SpringBoot默认提供了程序出错的结果映射路径/error,这个请求的处理逻辑在BasicErrorController中处理,处理逻辑如下:

// 判断mediaType类型是否为text/html @RequestMapping(produces = MediaType.TEXT_HTML_VALUE) public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { HttpStatus status = getStatus(request); Map<String, Object> model = Collections .unmodifiableMap(getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.TEXT_HTML))); response.setStatus(status.value()); // 创建ModelAndView对象,返回页面 ModelAndView modelAndView = resolveErrorView(request, response, status, model); return (modelAndView != null) ? modelAndView : new ModelAndView("error", model); } @RequestMapping public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) { HttpStatus status = getStatus(request); if (status == HttpStatus.NO_CONTENT) { return new ResponseEntity<>(status); } Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL)); return new ResponseEntity<>(body, status); } 二、错误页面的定制

相信Whitelabel Error Pag页面我们经常会遇到,这样体验不是很好,在SpringBoot中可以尝试定制错误页面,定制方式主要分静态和动态两种:

静态异常页面

在classpath:/public/error或classpath:/static/error路径下定义相关页面:文件名应为确切的状态代码,如404.html,或系列掩码,如4xx.html。

举个例子,如果你想匹配404或5开头的所有状态代码到静态的html文件,你的文件目录应该是下面这个样子:

src/ +- main/ +- java/ | + <source code> +- resources/ +- public/ +- error/ | +- 404.html | +- 5xx.html +- <other public assets>

如果500.html和5xx.html同时生效,那么优先展示500.html页面。

使用模板的动态页面

放置在classpath:/templates/error路径下:这里使用thymeleaf模板举例:

src/ +- main/ +- java/ | + <source code> +- resources/ +- templates/ +- error/ | +- 5xx.html +- <other templates>

页面如下:

<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>5xx</title> </head> <body> <h1>5xx</h1> <p th:text="'error -->'+ ${error}"></p> <p th:text="'status -->' + ${status}"></p> <p th:text="'timestamp -->' + ${timestamp}"></p> <p th:text="'message -->' + ${message}"></p> <p th:text="'path -->' +${path}"></p> <p th:text="'trace -->' + ${trace}"></p> </body> </html>

如果静态页面和动态页面同时存在且都能匹配,SpringBoot对于错误页面的优先展示规则如下:

如果发生了500错误:

动态500 -> 静态500 -> 动态5xx -> 静态5xx

三、自定义异常数据

默认的数据主要是以下几个,这些数据定义在org.springframework.boot.web.servlet.error.DefaultErrorAttributes中,数据的定义在getErrorAttributes方法中。

SpringBoot中的全局异常处理

DefaultErrorAttributes类在org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration自动配置类中定义:

@Bean @ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT) public DefaultErrorAttributes errorAttributes() { return new DefaultErrorAttributes(); }

如果我们没有提供ErrorAttributes的实例,SpringBoot默认提供一个DefaultErrorAttributes实例。

因此,我们就该知道如何去自定义异常数据属性:

实现ErrorAttributes接口。

继承DefaultErrorAttributes,本身已经定义对异常数据的处理,继承更具效率。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjgyd.html