老項目改造返回值規範化

背景:

已經運行的項目,開始由於趕工期等因素,未做統一的接口返回規範。現在要做規範化,還必須要保留原先的接口,尤其是APP的接口,有的版本會存在一個比較長的時間。因此需要保留兩個版本,又不想維護兩套代碼。

使用ResponseBodyAdvice 攔截獲取controller的response body內容

basePackages 指定需要攔截的包 supports 返回是否需要攔截 通過返回類型、請求路徑匹配、header中的參數值等過濾請求內容,然後重寫返回對象,返回值。

@Slf4j
@ControllerAdvice(basePackages = "com.paw.response")
public class ApiResponseBodyAdvice implements ResponseBodyAdvice {

  @Override
  public boolean supports (MethodParameter methodParameter, Class converterType) {
  // 可以過濾攔截哪些內容 比如方法類型
    boolean supported = methodParameter.getMethod().getReturnType().equals(Result.class);
    return true;
  }

  @Override
  public Object beforeBodyWrite (Object body, MethodParameter methodParameter, MediaType selectedContentType, Class selectedConverterType,
      ServerHttpRequest request,
      ServerHttpResponse response) {
    String path = request.getURI().getPath();
    String klassMethod = methodParameter.getMethod().getDeclaringClass().getName() + "#" + methodParameter.getMethod().getName();
    log.info("request uri: {} method: {}", path, klassMethod);

    if(body instanceof String){
      Result result = new Result(200,"success",body);
      return JSONUtil.toJsonStr(result);
    }
    if (!(body instanceof Result)) {
      return body;
    }
    Result result = (Result) body;
    // 通過Path匹配,或者header中的值 來過濾請求
    AntPathMatcher pathMatcher = new AntPathMatcher();
    boolean matched = pathMatcher.match("/api/newUri/**", path);
    log.info("path match {} {}", path, matched);
    if (matched) {
      // 重寫返回碼 result.setCode(newCode);
    }
    // 生成新的規範化轉碼 newCode
    // result.setCode(newCode);

    return result;
  }

}

Result.java

@Data
public class Result<T> {

  private Integer code;
  private String message;
  private Object content;

  public Result () {
  }

  public Result (Integer code, String message, Object content) {
    this.code = code;
    this.message = message;
    this.content = content;
  }
}

測試請求,對 /resCode 請求攔截後重寫返回對象,對返回類型爲Result重寫規範化後的值setCode,setMessage.

@RestController
public class ResController {

  @GetMapping("/resCode")
  public Object resCode(){
    return "this is response data";
  }

  @GetMapping("/standardResCode")
  public Result standardResCode(){
    return new Result(200,"Success","standardResCode");
  }
}

訪問 http://localhost:8080/resCode返回

{"code":200,"message":"success","content":"this is response data"}

方式二 通過攔截器Interceptor 或者自定義Aop攔截重設返回值。

項目中一般會爲某個業務分配一個值段如810xxx,每個業務定義一個枚舉存放返回值code、message.

作者:lvzhyt
鏈接:https://juejin.cn/post/6972505207833886756
來源:掘金

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