一:先看看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的子类】,放在容器中,来达到自定义效果
原文地址:https://www.cnblogs.com/REdrsnow/p/10630921.html