java利用注解及反射给属性增加别名,解决请求参数名违反驼峰规范的问题
碰到一个情况,现在你需要与其他程序收发请求
如果你发送请求的参数不是驼峰式命名,你又想用类里的属性名当作请求参数名
此时可以在字段上加上一个自定义注解,在发送请求构造参数的时候使用注解里的别名,看代码
// 自定义注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation{
String value();
}
// 请求的父类,以及构造请求参数
public class BaseRequest implements Serializable {
// 在请求参数上加自定义的注解,value 是对方需要的参数名
// 比如 merchantId(小写 m),但是对方需要的参数名是 MerchantId(大写 M)
@CustomAnnotation("MerchantId")
private String merchantId;
// 在构造参数的时候,就可以通过反射获取自定义注解里的值,也就是给参数设置的别名
public static <T extends BaseRequest> Map<String, String> constructParams(T t, Map<String, String> requestMap) {
Map<String,String> resultMap = new HashMap<String, String>();
List<Field> fields = new ArrayList<>();
// 获取类字段,和值
fields.addAll(Arrays.asList(t.getClass().getDeclaredFields()));
fields.addAll(Arrays.asList(t.getClass().getSuperclass().getDeclaredFields()));
try {
for (Field field : fields) {
//抓所有的私有属性
if(Modifier.isPrivate(field.getModifiers())) {
String name = field.getName();
// 设置允许访问私有类
field.setAccessible(true);
// 格式化请求参数字段
Object f = field.get(t);
//属性不为空,设置到map中
if(f!=null) {
// 属性名和接口需要的参数名不一样,需要用注解里的名字
CustomAnnotation anno = field.getAnnotation(CustomAnnotation.class);
resultMap.put(anno.value(), f.toString());
}else {
//属性为空,尝试从requestMap取值
String v = requestMap.get(name);
if(StringUtils.isNotEmpty(v)) {
// 属性名和接口需要的参数名不一样,需要用注解里的名字
CustomAnnotation anno = field.getAnnotation(CustomAnnotation.class);
resultMap.put(anno.value(), v);
}
}
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return resultMap;
}
}
这种情况就是如果实体类之间有继承关系
一个请求一个类的构造参数有些麻烦,如果直接把请求参数名设置到类中又违反了规范
用自定义注解加反射来设置以及获取字段的别名,继而放到请求参数名中
由父类统一构造请求参数,不失为一种解决办法。