SpringMVC 統一異常處理JSON返回

1. 自定義異常類

定義接口

public interface Error {
    Integer getCode();
    String getMessage();
}

先定義一個抽象類爲基類,並創建基本的錯誤信息枚舉

public abstract class AbstractBaseError {

    public enum BaseErrorEnum implements Error {
        ACCOUNT_PASSWORD_FAIL(10001, "賬號或密碼錯誤!"),
        FORMAT_ERROR(10002, "格式錯誤【%s】")
        ;

        private int code;
        private String message;

        BaseErrorEnum(int code, String message) {
            this.code = code;
            this.message = message;
        }

        public BaseErrorEnum format(Object... param) {
            this.message = String.format(message, param);
            return this;
        }

        @Override
        public Integer getCode() {
            return this.code;
        }

        @Override
        public String getMessage() {
            return this.message;
        }
    }

}

自定義異常類,繼承RuntimeException

public class CustomException extends RuntimeException {

    private int code;

    public CustomException() {
    }

    public CustomException(Error error) {
        super(error.getMessage());
        this.code = error.getCode();
    }

    public CustomException(int code, String message) {
        super(message);
        this.code = code;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    @Override
    public String getMessage() {
        return super.getMessage();
    }

}

各個子系統的話可以繼承AbstractBaseError,再創建子系統的錯誤信息枚舉

public class Test1Error extends AbstractBaseError {

    public enum ErrorEnum implements Error {
        TEST1_ERROR_1(11000, "test1 錯誤1!"),
        ;

        private int code;
        private String message;

        ErrorEnum(int code, String message) {
            this.code = code;
            this.message = message;
        }

        public ErrorEnum format(Object... param) {
            this.message = String.format(message, param);
            return this;
        }

        @Override
        public Integer getCode() {
            return this.code;
        }

        @Override
        public String getMessage() {
            return this.message;
        }
    }

}

2. 統一異常處理

@ControllerAdvice 控制器增強,而@RestControllerAdvice相當於@ResponseBody + @ControllerAdvice
@ExceptionHandler 攔截異常,統一處理

@RestControllerAdvice
public class GlobalExceptionHandler {

    @Autowired
    private HttpServletResponse response;

    /**
     * 處理異常Exception的返回
     * @param request
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public Map ExceptionHandler(HttpServletRequest request, Exception e) {
        e.printStackTrace();

        Map<String, Object> result = new HashMap<>(2);
        result.put("code", 500);
        String requestUri = request.getRequestURI();

        if (requestUri.contains("/api/")) {
            result.put("message", "內部異常!");
        } else {
            if (e.getMessage() == null) {
                result.put("message", "內部異常!");
            } else {
                result.put("message", e.getMessage());
            }
        }

        response.setStatus(500);
        return result;
    }

}

測試:

@GetMapping("/exception")
public void exception(){
    throw new RuntimeException("測試錯誤錯誤");
}

@GetMapping("/test1Error")
public void test1Error(){
    throw new CustomException(Test1Error.ErrorEnum.TEST1_ERROR_1);
}

@GetMapping("/formatError")
public void formatError(){
    throw new CustomException(Test1Error.BaseErrorEnum.FORMAT_ERROR.format("格式化的內容"));
}

exception錯誤
test1錯誤
格式化錯誤

參考:
SpringMVC 中 @ControllerAdvice 註解的三種使用場景!
springmvc 通過異常增強返回給客戶端統一格式
Spring 異常處理三種方式 @ExceptionHandler

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