学习小片段——springboot 错误处理

一:先看看springboot默认的错误处理机制

springboot默认会判断是否是浏览器(http请求头Accept是否含有 text/html)来选择返回html错误页面或json错误信息

 原因在于BasicErrorController 控制器中的这两个映射

  errorHtml响应来自浏览器的请求,而error响应来自其他客户端的请求;

  在errorHtml中最后两句,如果没有自定义的页面,就会使用系统默认的错误解析视图

二:那么如何定制自己的错误页面呢?

 由BasicErrorController 控制器中errorHtml的最后调用

1 ModelAndView modelAndView = resolveErrorView(request, response, status, model);

获取用户自定义的对应的错误页面

 (DefaultErrorViewResolver)

resolve方法或先查找模板引擎的页面中是否有error/(错误状态码) 页面,如果有就直接返回视图,如果没有就查找静态资源文件下有没有,如果也没有就返回null,使用springboot默认的

这样的话,我们就只需要在模板引擎解析目录或者静态资源目录的error文件夹下放入(错误状态码).html 即可,(也可以是4xx , 5xx)

模板页面里能获取到一些信息

timestamp:时间戳
status:状态码
error:错误提示
exception:异常对象
message:异常消息
errors:JSR303数据校验的错误都在这里

例如:(我是thymleaf)

 1 <!DOCTYPE html>
 2 <html lang="en"  xmlns:th="http://www.thymeleaf.org">
 3 <head>
 4     <meta charset="UTF-8">
 5     <!--/*@thymesVar id="status" type="java"*/-->
 6     <title th:text="${status}"></title>
 7 </head>
 8 <body>
 9 <h2>timestamp : [[${timestamp}]]</h2>
10 <h2>status : [[${status}]]</h2>
11 <h2>error : [[${error}]]</h2>
12 <h2>exception : [[${exception}]]</h2>
13 <h2>message : [[${message}]]</h2>
14 <h2>errors : [[${errors}]]</h2>
15 </body>
16 </html>

 

三:定制json格式错误响应

利用自定义异常处理机制来定制json数据响应

 1 @ControllerAdvice
 2 public class MyExceptionHandler {
 3     @ResponseBody
 4     @ExceptionHandler(Exception.class)
 5     public Map<String, Object> exceptionHandler1(Exception e){
 6         Map<String, Object> map = new HashMap<>();
 7         map.put("status", 400);
 8         map.put("msg", e.getMessage());
 9         map.put("data", null);
10         return map;
11     }
12 }
1     @GetMapping("/222")
2     public void test4(){
3         throw new RuntimeException("23333");
4     }

四:需要像springboot默认的一样自动选择响应html页面还是json

html错误页面上的数据和json的数据都是通过errorAttributes.getErrorAttributes得到的,

所以我们可以在自定义异常处理中转发到/error, 并自定义ErrorAttributes,来实现

 1 @ControllerAdvice
 2 public class MyExceptionHandler {
 3     @ExceptionHandler(Exception.class)
 4     public String exceptionHandler1(Exception e, HttpServletRequest request){
 5         Map<String, Object> map = new HashMap<>();
 6         map.put("msg", e.getMessage());
 7         map.put("data", null);
 8         request.setAttribute("errorMap", map);
 9 
10         request.setAttribute("javax.servlet.error.status_code",400);
11 
12         return "forward:/error";
13     }
14 }
1 @Component
2 public class MyErrorAttributes extends DefaultErrorAttributes {
3     @Override
4     public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
5         Map<String, Object> map = (Map<String, Object>) requestAttributes.getAttribute("errorMap", 0);
6 
7         return map;
8     }
9 }

还有之前的4xx.html

效果:

五:完全由我们自己实现

编写一个ErrorController的实现类【或者是编写AbstractErrorController的子类】,放在容器中,来达到自定义效果

猜你喜欢

转载自www.cnblogs.com/REdrsnow/p/10630921.html
今日推荐