【SpringBoot教程】SpringBoot 统一异常处理(附核心工具类-ErrorInfoBuilder)

作者简介:大家好,我是撸代码的羊驼,前阿里巴巴架构师,现某互联网公司CTO

联系v:sulny_ann(17362204968),加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

# 序言

此前,我们主要通过在控制层(Controller)中手动捕捉异常(TryCatch)和处理错误,在SpringBoot 统一异常处理的做法主要有两种:一是基于注解ExceptionHandler,二是基于接口ErrorController,两者都可以让控制器层代码快速“瘦身”,让业务逻辑看起来更加清晰明朗!

一. 默认错误处理

SpringBoot 默认为我们提供了BasicErrorController 来处理全局错误/异常,并在Servlet容器中注册error为全局错误页。所以在浏览器端访问,发生错误时,我们能及时看到错误/异常信息和HTTP状态等反馈。工作原理如下:

@Controller@RequestMapping("${server.error.path:${error.path:/error}}")public class BasicErrorController extends AbstractErrorController {
      // 统一异常处理(View)    @RequestMapping(produces = "text/html")    public ModelAndView errorHtml(HttpServletRequest request,            HttpServletResponse response) {
          HttpStatus status = getStatus(request);        Map model = Collections.unmodifiableMap(getErrorAttributes(                request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));        response.setStatus(status.value());        ModelAndView modelAndView = resolveErrorView(request, response, status, model);        return (modelAndView == null ? new ModelAndView("error", model) : modelAndView);    }
 
  

例如下面这两个错误,对于日常开发而言,再熟悉不过了。

【SpringBoot教程】SpringBoot 统一异常处理(附核心工具类-ErrorInfoBuilder)_第1张图片

404 Not Found

【SpringBoot教程】SpringBoot 统一异常处理(附核心工具类-ErrorInfoBuilder)_第2张图片

500 服务器错误

二. 统一异常处理

默认的英文空白页,显然不能够满足我们复杂多变的需求,因此我们可以通过专门的类来收集和管理这些异常信息,这样做不仅可以减少控制层的代码量,还有利于线上故障排查和紧急短信通知等。

具体步骤

为了让小伙伴少走一些弯路,楼主根据官方源码和具体实践,提炼这些核心工具类:

  • ErrorInfo  错误信息

  • ErrorInfoBuilder 错误信息的构建工具

注:在CSDN和大牛博客中,不乏关于Web应用的统一异常处理的教程,但更多的是基础学习使用,并不能投入实际项目使用,为了让大家少走一些弯路和快速投入生产,楼主根据官方源码和项目实践,提炼出了核心工具类(ErrorInfoBuilder ),将构建异常信息的逻辑从异常处理器/控制器中抽离出来,让大家通过短短几行代码就能获取丰富的异常信息,更专注于业务开发!!

1.  统一异常处理器(GlobalErrorHandler)

  • @ControllerAdvice  限定范围 例如扫描某个控制层的包

  • @ExceptionHandler  指定异常  例如指定处理运行异常。

具体如下:

​​​​​​​

package com.hehe.error;
@ControllerAdvicepublic class GlobalErrorHandler {
  
    private final static String DEFAULT_ERROR_VIEW = "error";//错误信息页
    @Autowired    private ErrorInfoBuilder errorInfoBuilder;//错误信息的构建工具
    /**     * 根据业务规则,统一处理异常。     */    @ExceptionHandler(Exception.class)    @ResponseBody    public Object exceptionHandler(HttpServletRequest request, Throwable error) {
  
        //1.若为AJAX请求,则返回异常信息(JSON)        if (isAjaxRequest(request)) {
             return errorInfoBuilder.getErrorInfo(request,error);        }        //2.其余请求,则返回指定的异常信息页(View).        return new ModelAndView(DEFAULT_ERROR_VIEW, "errorInfo", errorInfoBuilder.getErrorInfo(request, error));    }
    private boolean isAjaxRequest(HttpServletRequest request) {
  
        return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));    }
}
 
  

2. 统一异常信息(ErrorInfo)

虽然官方提供了ErrorAttributes来存储错误信息,但其返回的是存储结构是Map,为了更好的服务统一异常,这里我们统一采用标准的ErrroInfo来记载错误信息。

​​​​​​​

package com.hehe.error;
public class ErrorInfo {
  
    private String time;//发生时间    private String url;//访问Url    private String error;//错误类型

你可能感兴趣的:(springboot,springboot)