springboot接口返回封裝與異常控制
阿新 • • 發佈:2019-04-12
return odi instance response ria 如果 style 全局異常 append
首先,返回有兩個狀態,status和code
status標識response的狀態,有2個值:0成功,-1服務錯誤。
code跟業務有關,可以有各種數值,99999服務未知異常,10000參數異常,100001創建訂單失敗等等。這兩個狀態用枚舉類表示。
ResponseStatus
/** * @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; } }
ResponseCode
/** * @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。
Response
/** * @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。
我這個advice會捕捉ApiException(自定義),一般用業務Code碼裏的錯誤碼和信息,這時候我們可以返回提示性異常。然後就是Exception普通異常,一般提示服務器未知錯誤。
我這裏還處理了一個參數校驗異常
/** * @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); } }
springboot接口返回封裝與異常控制