Java:使用属性注解对应第三方接口的参数名称

背景

  在开发过程中,如果第三方接口参数的命名遵循一定的规范,我方在封装请求体时会比较方便和整洁,通常不需要过多的注释。但是如果第三方接口的参数命名非常随意呢?我们知道,如果是POST 请求,我们可以使用 JSONField 。但如果是让我们自己不依赖 fastjson 来完成一个GET请求的字符串拼接呢?

比如:

/api/addUser?NAME=xiaoguaiguai&agenumber=78&sex_flag=0&ji_Guan=东北那旮

  它揉合了多种命名规则并且还包含拼音,这个时候你应该如何保证自己的代码是整洁的呢?

1.定义属性注解

  由于属性对应的参数名称非常随意,我们准备手动记录它,这样呢,我们就需要一个注解:

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(value={ElementType.FIELD})
@Documented
@Inherited
public @interface ThirdApiParamName {

    /**
     * 参数名称
     *
     * @return
     */
    String value();

}

2. 对应参数信息体添加属性注解

  注解使用时非常简单,比如我们有一个UserAddDTO.class,直接进行标记。

@Data
public class UserAddDTO{

    /**
     * 用户名称
     */
    @ThirdApiParamName("NAME")
    private String name;
    /**
     * 用户年龄
     */
	@ThirdApiParamName("agenumber")
	private int age;
	/**
     * 性别标志
     * 0:女
     * 1:男
     */
	@ThirdApiParamName("sex_flag")
	private int sexFlag;
	/**
     * 籍贯
     */
	@ThirdApiParamName("ji_Guan")
	private String nativePlace;
}

  这样写有什么好处呢?假如另外一个人,从日志看到了打印的请求的 url 字符串,发现了一个诡异的参数叫agenumber,他就开始Ctrl+Shift+F搜索,正好发现了这个类,一看你的注释,他就能明白:啊,原来是年龄,他把两个单词写一块了。

3.Java反射解析注解

  下面我们使用反射机制,获取到对应的属性上的注解中填写的值以及属性的值,进行拼接。这一部分我们可以写在工具类里,当然如果你DDD,你可以有自己的考量,我这里只给出函数体:

public static String fulfilledUrlWithParams(String urlPrefix, Object paramObject) {
        try {
            Class<?> aClass = paramObject.getClass();
            Field[] declaredFields = aClass.getDeclaredFields();
            StringBuilder stringBuffer = new StringBuilder(urlPrefix);
            stringBuffer.append("?");
            StringJoiner paramStringJoiner = new StringJoiner("&");
            for (Field declaredField : declaredFields) {
                // 对应每个属性,获取它对应的参数的名称
                declaredField.setAccessible(true);
                Object valueObj = declaredField.get(paramObject);
                if (valueObj == null || StringUtils.isBlank(valueObj.toString())) {
                    continue;
                }
                ThirdApiParamName paramName= declaredField.getAnnotation(ThirdApiParamName.class);
                if (paramName== null) {
                    continue;
                }
                paramStringJoiner.add(paramName.value() + "=" + valueObj);
            }
            stringBuffer.append(paramStringJoiner.toString());
            return stringBuffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

  这样,我们就把一个毫无命名规律的第三方接口参数规范化了。这样,我们在封装好了整个请求服务后,开发组内部就是用我们自己写的服务了,而不是各自去面对第三方混乱的接口参数。

  其实这个设计并不难想到,只要你熟悉门面模式、代理模式、适配器模式,你会很自然想到要添加一个中间层,以屏蔽一些麻烦的细节。其实,编程中涉及到设计相关的内容,大部分都是中间层的艺术。

思考题

  接下来,留一个思考题给每一位读者:

在你的项目中,如果是遇到同事之间的接口调用,对方参数命名不规范,你应该怎么做呢?

  欢迎你在评论区留言,和其他读者进行讨论。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值