【spring】-- springboot配置全局异常处理器

一、为什么要使用全局异常处理器?

什么是全局异常处理器?

就是把错误异常统一处理的方法。

应用场景

1、当你使用jsr303参数校验器,如果参数校验不通过会抛异常,而且无法使用try-catch语句直接捕获,这时可以使用全局异常处理器来捕捉该异常。

2、当你自定义了一个异常类,可以在全局异常处理器中来捕捉该异常。(当然也可以直接在抛出异常处直接捕获,但是这样需要在每一个抛出的地方都写一次捕获代码,看起来不够美观且复用性不强,其他异常同理)。

 

所有异常都可以在全局异常处理器中捕获进行统一处理

二、具体使用步骤

1、定义统一的请求返回类型

public class Result<T> {
    private int code;
    private String msg;
    private T data;
    
    /**
     * 请求成功时调用
     * @param data
     * @return
     */
    public static <T> Result<T> success(T data){
        return new Result<T>(data);
    }
    
    public static <T> Result<T> error(CodeMsg cm){
        return new Result<T>(cm);
    }
    
    /**
     * 只传入数据默认成功,所以添加默认的code和msg
     * @param data
     */
    private Result(T data) {
        this.code=0;
        this.msg="success";
        this.data=data;
    }
    
    private Result(CodeMsg cm) {
        if(cm==null){
            return;
        }
        this.code=cm.getCode();
        this.msg=cm.getMsg();
    }
    
    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    public T getData() {
        return data;
    }

}
public class CodeMsg {

    private int code;
    private String msg;
    
    //通用的错误码
    public static CodeMsg SUCCESS = new CodeMsg(0, "success");
    public static CodeMsg SERVER_ERROR = new CodeMsg(500100, "服务端异常");
    public static CodeMsg BIND_ERROR = new CodeMsg(500101, "参数校验异常:%s");
    //登录模块 5002XX
    public static CodeMsg SESSION_ERROR = new CodeMsg(500210, "Session不存在或者已经失效");
    public static CodeMsg PASSWORD_EMPTY = new CodeMsg(500211, "登录密码不能为空");
    public static CodeMsg STUDENTID_EMPTY = new CodeMsg(500212, "学号不能为空");
    public static CodeMsg STUDENTID_ERROR = new CodeMsg(500213, "学号格式错误");
    public static CodeMsg STUDENTIDE_NOT_EXIST = new CodeMsg(500214, "学号不存在");
    public static CodeMsg PASSWORD_ERROR = new CodeMsg(500215, "密码错误");
    
    public int getCode() {
        return code;
    }


    public String getMsg() {
        return msg;
    }
    
    public CodeMsg fillArgs(Object... args) {
        int code = this.code;
        String message = String.format(this.msg, args);
        return new CodeMsg(code, message);
    }


    private CodeMsg(int code,String msg) {
        this.code = code;
        this.msg = msg;
    }

}

2、定义自己的异常类

public class GlobalException extends RuntimeException{

    private static final long serialVersionUID = 1L;
    
    private CodeMsg cm;
    
    public GlobalException(CodeMsg cm) {
        super(cm.toString());
        this.cm = cm;
    }

    public CodeMsg getCm() {
        return cm;
    }

}

3、定义全局异常处理器

@ControllerAdvice //该注解定义全局异常处理类
//@ControllerAdvice(basePackages ="com.example.demo.controller") 可指定包
@ResponseBody
public class GlobalExceptionHandler {
    @ExceptionHandler(value=Exception.class) //该注解声明异常处理方法
    public Result<String> exceptionHandler(HttpServletRequest request, Exception e){
        e.printStackTrace();
        //对于自定义异常的处理
        if(e instanceof GlobalException) {
            GlobalException ex = (GlobalException)e;
            return Result.error(ex.getCm());
        //对于绑定异常的处理,使用jsr303中的自定义注解抛出的异常属于绑定异常
        }else if(e instanceof BindException) {
            BindException ex = (BindException)e;
            List<ObjectError> errors = ex.getAllErrors();
            ObjectError error = errors.get(0);
            String msg = error.getDefaultMessage();
            return Result.error(CodeMsg.BIND_ERROR.fillArgs(msg));
        }else {
            return Result.error(CodeMsg.SERVER_ERROR);
        }
    }
}

4、使用自己的定义的异常类

if(user == null) {
    throw new GlobalException(CodeMsg.STUDENTIDE_NOT_EXIST);
}

 

看到的更容易理解一篇文章:https://www.cnblogs.com/zs-notes/p/9366066.html

 

posted @ 2019-03-23 11:31  健忘的李鸽鸽  阅读(6653)  评论(0编辑  收藏  举报