老项目改造返回值规范化

举报
琴岛蛏子 发表于 2022/03/20 23:58:40 2022/03/20
【摘要】 老项目改造返回值规范化 背景:已经运行的项目,开始由于赶工期等因素,未做统一的接口返回规范。现在要做规范化,还必须要保留原先的接口,尤其是APP的接口,有的版本会存在一个比较长的时间。因此需要保留两个版本,又不想维护两套代码。 使用ResponseBodyAdvice 拦截获取controller的response body内容basePackages 指定需要拦截的包supports 返...

老项目改造返回值规范化

背景:

已经运行的项目,开始由于赶工期等因素,未做统一的接口返回规范。现在要做规范化,还必须要保留原先的接口,尤其是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.

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。