Loading...
墨滴

故事与你

2021/06/09  阅读:43  主题:科技蓝

深入springboot的异常处理(一)

电池焦虑:

对于异常,生活中也是面对生活不确定性的考验,比如我们手机在快没电的时候,我们会焦急的给它供电,防止断电影响我们的工作和生活体验, 一个产品或者在项目在实际的运行中,随之环境和场景的变化,出现的问题也是多种多样的,比如我造一辆车,我既要考虑,高温,车内的温度,助于散热,防止安全事故发生,或者采用报警提示的方式,这就是一个对待异常处理的方式。

如果解决不了,就抛出来,这也是我学异常之前,老师交给我们的第一句话,第二句可就是自己改了,我们继续开始,这期的主要是关于从springboot出发探究一下底层的异常机制:

异常

对于异常,指的是在项目编译或者运行过程中所出现的异常情况,比如参数转换,类型异常,数组越界,空指针等多个异常。

这次用的版本是springboot 2.2.13GA版本

springboot的官方文档地址

在springBoot Features中 (特性)中找到

异常
异常

springboot的关于errorHandler文档地址

错误处理

springboot默认有错误的机制,分为两种 全局的异常处理,定制的异常处理;

全局异常处理:

其实在设计框架的时候,就已经配置了关于运行过程中的异常问题,

全局异常处理原理:

利用的是@ControllerAdvice ,表示的是我们定义了一个控制器增强类,当其他任何控制器发送异常的时候,且服务@ExceptionHandler注解中制定的异常类时候,当前的请求都会被拦截到我们定义的此控制器类中

本质上时: 控制器增强器捕获,具体异常拦截做匹配

创建统一异常处理类

GlobalExceptionHandler

测试类:

@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 参数解析失败
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result handleHttpMessageNotReadableException(HttpMessageNotReadableException ex) {
        log.error("参数解析失败", ex);
        return Result.failCode202("参数解析失败");
    }

    /**
     * 参数验证异常
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        log.error("参数验证异常", ex);
        BindingResult result = ex.getBindingResult();
        FieldError error = result.getFieldError();
        String field = error.getField();
        String code = error.getDefaultMessage();
        String message = String.format("%s:%s", field, code);
        return Result.failCode202("参数验证异常:" + message);
    }

    /**
     * 参数验证异常
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(ValidationException.class)
    public Result handleValidationException(ValidationException ex) {
        log.error("参数验证异常", ex);
        return Result.failCode202("参数验证异常");
    }

    /**
     * 不支持当前请求方法
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Result handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException ex) {
        log.error("不支持当前请求方法", ex);
        return Result.failCode202("不支持当前请求方法");
    }


   
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(UnauthorizedException.class)
    public Result handle401() {
        return Result.failCode403("权限不足");
    }

    /**
     * 业务处理异常
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(UospException.class)
    public Result handleUospException(UospException ex) {
        log.error("业务处理异常", ex);
        return Result.failCode202(ex.getMessage());
    }


    /**
     * 捕捉其他所有异常
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    public Result globalException(Throwable ex) {
        log.error("异常信息", ex);
        return Result.fail(HttpConstants.STATUS_500, "系统异常");
    }

}

总结

对于全局的异常,根据异常控制器增强的注解, 然后根据定制化的区分异常类型,从而做到匹配化的触发定制的异常处理,其中还需要注意的一点是,关于

  • 1 @ExceptionHandler注解只有一个value参数,为指定的异常类;
@ExceptionHandler(MyException.class)
  • 2 @ControllerAdvice注解查看源码参数发现我们还可以指定需要拦截的控制器所在的包路径。

今天的分享就到这里了,期待下次关于自定义springboot的异常统一处理,是利用@AbstractErrorController,底层还是这个类

我是卢卡,今晚是苹果开发者大会,我得去瞅瞅最新可能要发布的M1X,记得点赞再走哦。

故事与你

2021/06/09  阅读:43  主题:科技蓝

作者介绍

故事与你