軟件加密狗複製

在項目中經常出現系統異常的情況,比如NullPointerException等等。如果默認未處理的情況下,springboot會響應默認的錯誤提示,這樣對用戶體驗不是友好,系統層面的錯誤,用戶不能感知到,即使爲500的錯誤,可以給用戶提示一個類似服務器開小差的友好提示等。這時候便可以使用全局異常處理器來優雅的處理全局異常
定義錯誤消息類

在全局錯誤類中會使用該錯誤消息進行初始化

注意該消息的toString方法要寫成Json格式的

具體的錯誤消息初始化的時候也可以使用%s一類的佔位符,後期調用靜態方法,來填充多個參數

@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());
// }

}
複製代碼定義全局異常類

之後遇到什麼錯誤,可以用錯誤消息類初始化全局異常類,並拋出該異常,該異常之後會被全局異常處理器捕獲

//繼承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;
}

}

複製代碼定義返回結果類

返回結果有兩種,一種是返回相應的錯誤碼,一種是返回正確的驗證碼+數據,因此我們編寫返回結果類

@Data
@ApiModel(description = “返回結果”)
public class Result 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);
}

}
複製代碼定義全局異常處理器

使用@ControllerAdvice來指定全局異常處理

使用@RestController返回json數據

使用@ExceptionHandler來捕獲特定的異常種類

@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";
// }

}
複製代碼效果
至此,便完成了自定義的全局異常處理方法,訪問效果如下
//成功
{
code = 0;
msg = “success”;
data = 456;
}

//失敗
{
code = 500100;
msg = “服務器錯誤”;
data = null;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章