0%

SpringBoot-错误处理机制

SpringBoot-错误处理机制

原理

可以参照ErrorMvcAutoConfiguration,错误处理的自动配置

给容器中添加了以下组件

  • DefaultErrorAttributes:

    帮我们在页面共享信息

  • BasicErrorController:

    处理默认的/error请求,返回html数据或json数据

  • ErrorPageCustomizer:

    系统出现错误后,来到error请求进行处理

  • DefaultErrorViewResolver:

    默认SpringBoot可以去找到一个页面(error/xxx),模板引擎能解析页面地址就用模板引擎解析,模板引擎可用就返回到erorViewName指定的视图地址,不可用则就在静态资源文件夹下找errorViewName对应的页面

步骤:一旦系统出现4xx或5xx之类的错误,ErrorPageCustomizer就会生效(定制错误的响应规则);就会来到/error请求;就会被BasicErrorController处理:

响应页面:去哪个页面是由DefaultErrorViewResolver解析得到的

如何定制错误响应

如何定制错误的页面

  1. 有模板引擎的情况下:error/状态码
    • 将错误页面命名为错误状态码.html放在resources/templates文件夹里面的error文件夹下,发生此状态码的错误就会来到对应的页面
    • 可以使用4xx和5xx作为错误页面的文件名来匹配这种类型的所有错误,精确名(如404.html)优先
    • 页面能获取的信息:
      • timestamp:时间戳
      • status:状态码
      • error:错误提示
      • exception:异常对象
      • message:异常消息
      • errors:JSR303数据校验的错误
  2. 没有模板引擎(模板引擎下没有这个错误页面),静态资源文件夹下找
  3. 以上都没有错误页面,则默认到SpringBoot默认的错误提示页面

如何定制错误的json响应数据

  1. 自定义异常处理并返回定制json数据

    无法自适应,浏览器和客户端返回的都是json

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
        // 1. 浏览器客户端返回的都是json
    // @ExceptionHandler(UserNotExistExecption.class)
    // @ResponseBody
    // public Map<String,Object> handleExecption(Exception e){
    // Map<String, Object> map = new HashMap<>();
    // map.put("code", "user.notexist");
    // map.put("message",e.getMessage());
    // return map;
    // }

    @ExceptionHandler(Exception.class)
    public String handleExecption(Exception e, HttpServletRequest request){
    Map<String, Object> map = new HashMap<>();
    // 传入我们自己的错误状态码
    request.setAttribute("javax.servlet.error.status_code",500);
    map.put("code", "exception");
    map.put("message",e.getMessage());

    request.setAttribute("ext",map);

    // 转发到/error进行自适应处理
    return "forward:/error";
    }
  2. 转发到/error进行自适应处理

  3. 设置错误状态码

  4. 将定制数据携带出去

    • 完全编写一个ErrorController的实现在(或编写AbstractErrorController的子类),放在容器中

    • 页面上能用的数据或json返回能用的数据都是通过errorAttributes.getErrorAttributes得到

      • 容器中DefaultErrorAttributes.getErrorAttributes();默认进行数据处理的,可自定义ErrorAttributes

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        @Component
        public class MyErrorAttributes extends DefaultErrorAttributes {
        @Override
        public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        Map<String, Object> map = super.getErrorAttributes(webRequest, includeStackTrace);
        map.put("company","company");
        // 从request域中获取数据,0->request域
        Map<String ,Object> ext = (Map<String, Object>) webRequest.getAttribute("ext", 0);
        map.put("ext",ext)

        return map;
        }
        }