springboot接口返回封裝與異常控制

 

首先,返回有兩個狀態,status和code

status標識response的狀態,有2個值:0成功,-1服務錯誤。服務器

code跟業務有關,能夠有各類數值,99999服務未知異常,10000參數異常,100001建立訂單失敗等等。這兩個狀態用枚舉類表示。app

ResponseStatusui

/**
 * @Author: ivan
 * @Description: 服務狀態代碼
 * @Date: 18/11/26
 * @Modified By;
 */
public enum ResponseStatus {

    OK(0, "成功"),
    ERROR(-1, "服務錯誤");

    private int value;
    private String message;

    ResponseStatus(int value, String message){
        this.value = value;
        this.message = message;
    }

    public int getValue() {
        return value;
    }

    public String getMessage() {
        return message;
    }

}

 

 

ResponseCodethis

/**
 * @Author: ivan
 * @Description: 業務狀態代碼
 * @Date: 18/11/26
 * @Modified By;
 */
public enum ResponseCode {

    FORMAL(0, "業務正常"),
    INVALID_PARAM(100000, "參數錯誤"),
    UNKNOWN_FAILED(999999, "服務器未知錯誤"),
    SAVE_FAILED(888888, "保存失敗"),
    UPDATE_FAILED(777777, "保存失敗"),
    DELTE_FAILED(666666, "刪除失敗"),
    SEARCH_FLOW_FAILED(555555, "查詢任務流的執行詳情失敗!");

    private int value;
    private String message;

    ResponseCode(int value, String message){
        this.value = value;
        this.message = message;
    }

    public int getValue() {
        return value;
    }

    public String getMessage() {
        return message;
    }

}

 

而後,是Response類,簡單工廠模式,提供build方法,建立正常返回和錯誤返回Response。

Responsespa

/**
 * @Author: ivan
 * @Description: 返回值封裝
 * @Date: Created in 17:26 18/11/26
 * @Modified By:
 */
public class Response<T> implements Serializable {

    private int status;

    private int code;

    private String message;

    private Object data;

    public Response(ResponseStatus status, ResponseCode code, String message, T data) {
        this.setStatus(status);
        this.setCode(code);
        this.setMessage(message);
        this.setData(data);
    }

    public static <T> Response<T> buildSuccessResponse(T data) {
        return new Response<T>(ResponseStatus.OK, ResponseCode.FORMAL, null, data);
    }

    public static <T> Response<T> buildFailResponse(ResponseStatus responseStatus, ResponseCode responseCode,
                                                  String message, T data) {
        return new Response<T>(responseStatus, responseCode, message, data);
    }


    public int getStatus() {
        return status;
    }

    public void setStatus(ResponseStatus status) {
        this.status = status.getValue();
    }

    public int getCode() {
        return code;
    }

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

    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

 

若是不想在controller裏try-catch通常的異常,而且在必定的條件下經過throw控制代碼邏輯,咱們須要創建ControllerAdvice。code

我這個advice會捕捉ApiException(自定義),通常用業務Code碼裏的錯誤碼和信息,這時候咱們能夠返回提示性異常。而後就是Exception普通異常,通常提示服務器未知錯誤。blog

我這裏還處理了一個參數校驗異常ip

/**
 * @Author: ivan
 * @Description: 全局異常處理advice
 * @Date: Created in 20:21 18/11/26
 * @Modified By:
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
    *   處理全局異常handler, ApiException爲業務異常, 其餘爲服務器未知異常
    */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Response<String> handle(Exception e) {

        Response<String> response;

        if (e instanceof ApiException) {
            ApiException error = (ApiException) e;
            response = Response.buildFailResponse(ResponseStatus.ERROR, error.getResponseCode(),
                    error.getResponseCode().getMessage(), null);
        } else {
            response = Response.buildFailResponse(ResponseStatus.ERROR, ResponseCode.UNKNOWN_FAILED,
                    ResponseCode.UNKNOWN_FAILED.getMessage(), null);
        }

        logger.error("[Exception] message={}", e);

        return response;
    }


    /**
     *  處理參數校驗異常handler
     */
    @ExceptionHandler(ValidationException.class)
    @ResponseBody
    public Response<String> handle(ValidationException e) {

        StringBuilder sb = new StringBuilder();

        if(e instanceof ConstraintViolationException){

            ConstraintViolationException error = (ConstraintViolationException) e;
            Set<ConstraintViolation<?>> violations = error.getConstraintViolations();

            for (ConstraintViolation<?> item : violations) {
                sb.append(item.getMessage());
            }

        }

        logger.error("[Validation] message={}", sb.toString(), e);

        return Response.buildFailResponse(ResponseStatus.ERROR, ResponseCode.INVALID_PARAM, sb.toString(), null);

    }

}
相關文章
相關標籤/搜索