SpringBoot后端返回統一的標准格式數據


1.@RestControllerAdvice,RestController的增強類,可用於實現全局異常處理器
2.@ExceptionHandler,統一處理某一類異常,從而減少代碼重復率和復雜度,比如要獲取自定義異常可以@ExceptionHandler(BusinessException.class)
3.@ResponseStatus指定客戶端收到的http狀態碼

// 1.定義返回對象
@Data
public class ResultData<t> {
  /** 結果狀態 ,具體狀態碼參見ResultData.java*/
  private int status;
  private String message;
  private T data;
  private long timestamp ;

  public ResultData (){
    this.timestamp = System.currentTimeMillis();
  }

  public static <t> ResultData<t> success(T data) {
    ResultData<t> resultData = new ResultData<>();
    resultData.setStatus(ReturnCode.RC100.getCode());
    resultData.setMessage(ReturnCode.RC100.getMessage());
    resultData.setData(data);
    return resultData;
  }

  public static <t> ResultData<t> fail(int code, String message) {
    ResultData<t> resultData = new ResultData<>();
    resultData.setStatus(code);
    resultData.setMessage(message);
    return resultData;
  }

}

// 2.定義狀態碼
public enum ReturnCode {
    /**操作成功**/
    RC100(100,"操作成功"),
    /**操作失敗**/
    RC999(999,"操作失敗"),
    /**服務限流**/
    RC200(200,"服務開啟限流保護,請稍后再試!"),
    /**服務降級**/
    RC201(201,"服務開啟降級保護,請稍后再試!"),
    /**熱點參數限流**/
    RC202(202,"熱點參數限流,請稍后再試!"),
    /**系統規則不滿足**/
    RC203(203,"系統規則不滿足要求,請稍后再試!"),
    /**授權規則不通過**/
    RC204(204,"授權規則不通過,請稍后再試!"),
    /**access_denied**/
    RC403(403,"無訪問權限,請聯系管理員授予權限"),
    /**access_denied**/
    RC401(401,"匿名用戶訪問無權限資源時的異常"),
    /**服務異常**/
    RC500(500,"系統異常,請稍后重試"),

    INVALID_TOKEN(2001,"訪問令牌不合法"),
    ACCESS_DENIED(2003,"沒有權限訪問該資源"),
    CLIENT_AUTHENTICATION_FAILED(1001,"客戶端認證失敗"),
    USERNAME_OR_PASSWORD_ERROR(1002,"用戶名或密碼錯誤"),
    UNSUPPORTED_GRANT_TYPE(1003, "不支持的認證模式");

    /**自定義狀態碼**/
    private final int code;
    /**自定義描述**/
    private final String message;

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

    public int getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}

// 3.借助SpringBoot提供的ResponseBodyAdvice: 攔截Controller方法的返回值,統一處理返回值/響應體, 進一步封裝;
/**
 * 編寫實現類,統一處理返回值
 * @author
 * @date 2021/7/28 10:10 上午
 */
@RestControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice<object> {
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public boolean supports(MethodParameter methodParameter, Class<!--? extends HttpMessageConverter<?-->> aClass) {
        return true;
    }

    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<!--? extends HttpMessageConverter<?-->> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        if(o instanceof String){
            return objectMapper.writeValueAsString(ResultData.success(o));
        }        
        return ResultData.success(o);
    }
}

// 4. 進一步優化,全局異常處理
@Slf4j
@RestControllerAdvice
public class RestExceptionHandler {
    /**
     * 默認全局異常處理。
     * @param e the e
     * @return ResultData
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResultData<string> exception(Exception e) {
        log.error("全局異常信息 ex={}", e.getMessage(), e);
        return ResultData.fail(ReturnCode.RC500.getCode(),e.getMessage());
    }

}
// 5. 全局異常接入返回標准格式實現
@SneakyThrows
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<!--? extends HttpMessageConverter<?-->> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
  if(o instanceof String){
    return objectMapper.writeValueAsString(ResultData.success(o));
  }
  if(o instanceof ResultData){
    return o;
  }
  return ResultData.success(o);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM