超详细-SpringBoot统一异常处理解决思路

SpringBoot统一异常处理解决思路

对于一个完美的项目,异常处理是必不可少的。SpringBoot的统一异常处理,可以让项目出现的绝大多数异常都在你的把控之类。废话不多说,直接上干货。

首先先知道一下SpringBoot统一异常处理四剑客(四模板),1. 异常类型枚举类,2.自定义异常,3.统一信息返回类,4.全局异常处理类。现在不懂没关系,后面会讲。

在这里插入图片描述

第一个干货 @ControllerAdvice注解

@ControllerAdvice注解有三个用途,全局异常处理,全局数据绑定,全局数据预处理。因为本篇文章是讲统一异常处理的,所以我们这里只讲其全局异常处理的用法。

那么@ControllerAdvice有什么用呢?所以Controller抛出来的异常都能由被@ControllerAdvice注解的类来进行异常处理。当然还要结合@ExceptionHandler注解。上代码!

这里我们先不要关注R是什么,后面会将。@ControllerAdvice类注解注解标明这个类被用来处理Controller抛出来的所有异常。@ExceptionHandler方法加异常类的字节码对象参数标明该方法用来处理的异常类型。比如RRExceptionHandle方法用来处理RRException(自定义异常,后面会讲)这个异常及其子类,而如果Contrller抛出NullPointException异常则不会由RRExceptionHandle这个方法来处理。

/**
 * controller 统一异常处理
 */
@ControllerAdvice
public class CommonExceptionHandle {

    @ResponseBody
    @ExceptionHandler(RRException.class)
    public R RRExceptionHandle(RRException exception){
        return R.error(exception.getCode(),exception.getMsg());
    }

    @ResponseBody
    @ExceptionHandler(RuntimeException.class)
    public R RuntimeExceptionHandle(RuntimeException runtimeException){
        return R.error(500,runtimeException.getMessage());
    }
}

异常类型枚举类

异常枚举类,通过设置枚举类型和自定义异常结合起来,可以很方便的定义各种类型的异常。(@Getterd得装lombok插件才能使用)

@Getter
public enum ExceptionEnum {
    ADMINISTRATOR_UPDATE_FAILED(5000,"管理员更新错误"),
    ADMINISTRATOR_SAVE_FAILED(5001,"管理员保存错误"),
    ADMINISTRATOR_DELETE_FAILED(5002,"管理员删除错误")
    ;
    private final int code;
    private final String msg;
    ExceptionEnum(int code,String msg){
        this.code = code;
        this.msg = msg;
    }
}

使用场景

@PutMapping(value = "")
    public R update(@RequestBody AdministratorEntity administrator){
        logger.info("administrator update函数入参为:{}",administrator);
        boolean update = administratorService.updateById(administrator);
        if(!update){
            throw new RRException(ExceptionEnum.ADMINISTRATOR_UPDATE_FAILED);
        }
        logger.info("administrator update函数是是否成功为:{}",update);
        return R.ok().put("data","");
    }

自定义异常

自定义异常集成运行时异常类,提供一个异常枚举类的构造方法即可。

public class RRException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    private String msg;
    private int code = 500;

    public RRException(String msg) {
        super(msg);
        this.msg = msg;
    }
    public RRException(ExceptionEnum exceptionEnum) {
        super(exceptionEnum.getMsg());
        this.msg = exceptionEnum.getMsg();
        this.code = exceptionEnum.getCode();
    }
    public String getMsg() {
        return msg;
    }
    public int getCode() {
        return code;
    }

}

统一数据格式返回类

该类用来统一后台返回数据给前端的格式。

public class R extends HashMap<String, Object> {
    private static final long serialVersionUID = 1L;

    public R() {
        put("code", 0);
        put("msg", "success");
    }

    public static R error() {
        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
    }

    public static R error(String msg) {
        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
    }

    public static R error(int code, String msg) {
        R r = new R();
        r.put("code", code);
        r.put("msg", msg);
        return r;
    }

    public static R ok(String msg) {
        R r = new R();
        r.put("msg", msg);
        return r;
    }

    public static R ok(Map<String, Object> map) {
        R r = new R();
        r.putAll(map);
        return r;
    }

    public static R ok() {
        return new R();
    }


    public R put(String key, Object value) {
        super.put(key, value);
        return this;
    }
}

全局异常处理类

这边一个ExceptionHandle处理自定义异常,但是除了自定义异常可能还会有未知的异常,未知的异常也都是运行时异常,所以我们在添加一个方法用来处理未知异常。

@ControllerAdvice
public class CommonExceptionHandle {
    
    /**
     * 处理自定义异常
     */
    @ResponseBody
    @ExceptionHandler(RRException.class)
    public R RRExceptionHandle(RRException exception){
        return R.error(exception.getCode(),exception.getMsg());
    }
    /**
     * 处理未知错误
     */
    @ResponseBody
    @ExceptionHandler(RuntimeException.class)
    public R RuntimeExceptionHandle(RuntimeException runtimeException){
        return R.error(500,runtimeException.getMessage());
    }

}

版权声明:本文为qq_37129433原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。