2020 Teach you how to be elegant SpringBoot global exception handler

System abnormalities often the case in the project, such as NullPointerException and so on. If untreated by default, springboot will respond to a default error message, so the user experience is not a friendly system-level error, the user can not perceive, even if an error 500, may prompt a similar desertion server to the user-friendly tips Wait. This time you can use a global exception handler to deal with global exception elegant

Custom Error Messages class

  • The error message will be used to initialize the global exception class
  • Note that this message should be rewritten toString method Json format
  • Specific initialization error message can also be used when a class% s placeholder, late call the static method, a plurality of parameters to populate
  • This uses @Data notes omitted to write your own constructor, the details can find lombook use
@Data
@AllArgsConstructor
@Slf4j
public class CodeMsg implements Serializable {

    private int code;
    private String msg;

    public static CodeMsg SUCCESS = new CodeMsg(200, "success");
    public static CodeMsg SERVER_ERROR = new CodeMsg(500100, "服务器错误");
    public static CodeMsg INSERT_ERROR = new CodeMsg(500200, "插入错误");
    public static CodeMsg UNKNOWN_ERROR = new CodeMsg(-999, "未知错误:%s");
    //填充多个错误信息
    public static CodeMsg BIND_ERROR = new CodeMsg(500300,"参数校验异常:%s");
    public static CodeMsg UNSELECT_FILE_ERROR = new CodeMsg(500400,"未选择文件");
    public static CodeMsg FILE_NOT_EXIST_ERROR = new CodeMsg(500500, "文件或文件夹不存在");
    public static CodeMsg UPLOADING = new CodeMsg(500600, "正在上传");


    //补充未知错误的具体信息
    public CodeMsg fillArgs(Object... args){
        int code =  this.code;
        String message = String.format(this.msg,args);
        return new CodeMsg(code,message);
    }

    //处理异常时返回json的toString
    @Override
    public String toString() {
        return "CodeMsg{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                '}';
    }

    // public static void main(String[] args) {
    //     log.info(new CodeMsg(0, "hello").toString());
    // }
}

Define a global exception classes

  • After the encounter any errors, you can use the error message class initialization global exception class, and throw the exception, which will be captured after the global exception handler
//继承RuntimeException,并定义serialVersionUID
public class GlobalException extends RuntimeException {

    private static final long serialVersionUID = -3586828184536704147L;
    private CodeMsg codeMsg;

    public GlobalException(CodeMsg codeMsg) {
        super(codeMsg.toString());
        this.codeMsg = codeMsg;
    }

    public CodeMsg getCodeMsg() {
        return codeMsg;
    }
}

Return result defined class

  • Return result there are two, one is to return the corresponding error code, or by returning the correct code + data, so we write class return results
@Data
@ApiModel(description = "返回结果")
public class Result<T> implements Serializable {
    private int code;
    private T data;
    private String msg;

    private Result(T data) {
        this.code = 0;
        this.msg = "success";
        this.data = data;
    }

    private Result() {
        this.code = 0;
        this.msg = "success";
        this.data = null;
    }

    private Result(CodeMsg codeMsg) {
        if (codeMsg == null) {
            return;
        }
        this.code = codeMsg.getCode();
        this.msg = codeMsg.getMsg();
    }


    public static <T> Result<T> success(T data) {
        return new Result<T>(data);
    }

    public static <T> Result<T> success() {
        return new Result<T>();
    }
    public static <T> Result<T> error(CodeMsg codeMsg) {
        return new Result<T>(codeMsg);
    }

}

Define a global exception handler

  • Use @ControllerAdvice to specify global exception handler
  • Use @RestController return json data
  • Use @ExceptionHandler to capture a particular type of abnormality
@ControllerAdvice
@RestController
@Slf4j
public class GlobalExceptionHandler {

    //自定义异常类
    @ExceptionHandler(value = GlobalException.class)
    public Result<String> globalExceptionHandler(HttpServletRequest request, GlobalException e) {
        log.error(e.getCodeMsg().getMsg());
        return Result.error(e.getCodeMsg());
    }

    //参数检测不合格
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result<String> bindExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException e) {
        log.error(e.getClass().toString());
        // log.error(e.toString());
        List<ObjectError> errors = e.getBindingResult().getAllErrors();
        StringBuilder errorMsg = new StringBuilder();
        //此处仅取第一个
        // ObjectError objectError = errors.get(0);
        for (ObjectError error : errors) {
            errorMsg.append(error.getDefaultMessage()).append(" ");
        }
        // String errorMsg = objectError.getDefaultMessage();
        //填充具体异常
        return Result.error(CodeMsg.BIND_ERROR.fillArgs(errorMsg.toString()));
    }

    //其他异常类
    @ExceptionHandler(value = Exception.class)
    public Result<String> defaultExceptionHandler(HttpServletRequest request, Exception e) {
        log.error(e.getClass().toString());
        log.error(e.toString());
        e.printStackTrace();
        return Result.error(CodeMsg.UNKNOWN_ERROR.fillArgs(e.getClass().toString()));
    }

    //可定义详细的其他异常类
    // @ExceptionHandler(AuthenticationException.class)   //此处为shiro未登录异常类
    // @ResponseStatus(HttpStatus.UNAUTHORIZED)
    // public String unAuth(AuthenticationException e) {
    //     log.error("用户未登陆:", e);
    //     return "/login.html";
    // }
}

Effect
so far, we will complete the global self-defined exception handling, visit the following effect

 //成功
 {
    code = 0;
    msg = "success";
    data = 456;
 }
 
 //失败
 {
 	code = 500100;
 	msg = "服务器错误";
 	data = null;
 }

Above are some of my own thoughts, to share out the welcome to correct me, the way to find a wave of attention
Here Insert Picture Description
of: LeoMalik
link: https: //juejin.im/post/5e54796af265da575d20dd5d
Source: Nuggets

Published 19 original articles · won praise 7 · views 6443

Guess you like

Origin blog.csdn.net/ZYQZXF/article/details/104498839