spring boot 注解处理统一异常和自己编写接口来处理异常的区别

此前,我们主要通过在控制层(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<String, Object> 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);
    }

如下: 

二. 统一异常处理

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

具体步骤

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

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

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

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

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

具体如下:

package com.jaryle.error;

@ControllerAdvice
public 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<String,Object>,为了更好的服务统一异常,这里我们统一采用标准的ErrroInfo来记载错误信息。

package com.jaryle.error;

public class ErrorInfo {

    private String time;//发生时间
    private String url;//访问Url
    private String error;//错误类型
    String stackTrace;//错误的堆栈轨迹
    private int statusCode;//状态码
    private String reasonPhrase;//状态码

    //Getters And Setters
       ...
  
}

 

3. 统一异常信息的构建工具(ErrorInfoBuilder)

ErrorInfoBuilder 作为核心工具类,其意义不言而喻,重点API

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值