在很多的框架底层,都用到了java反射的原理,当初在学习java基础的时候,在反射这块,也只是稍稍的过了一下,因为一般只有需要写框架,或者去看框架的底层源码的时候,才会用到反射的知识点。
这次,工作中遇到一个问题,那就是需要使用java,充当一个中间商的角色,A服务调用我的java服务给我推送数据,我再通过公安提供的接口地址将数据推送给公安的服务,使用json格式来做中间数据的传输。但是,公安的接口文档中,所有的请求参数都是大写字母加下划线的格式,例如:
{
"MJJCJLXXBZ":"门禁进出XXX",
"GLDMJ_CJSBXXBZ":"关联的门禁采集XXX"
....
}
所有的接口的参数都是这种格式,大概有10几个接口,这些数据都是A服务推送给我的,所以就涉及到我这里需要写对应的Bean来接收这些参数,并将这些Bean转换成公安需要的json格式推送给公安。其实我完全可以用公安的这种数据格式,来声明一个个类,这样我就不用转换。
class Bean {
private String MJJCJLXXBZ;
private String GLDMJ_CJSBXXBZ;
....
}
这样做不是不可以,但是违反了java的小驼峰的命名方式,对于我这样有轻微洁癖的人是接受不了的,所以我将其换成常规的java小驼峰的命名格式。
class Bean {
private String mjjcjlxxbz;
private String gldmjCjsbxxbz;
....
}
这样A服务给我推送数据的时候,就采用这种小驼峰的格式,而我接收数据就使用这个bean来接收。但是我还需要将数据转换成公安接口需要的那种格式才能推送成功,传统办法是将bean里一个个字段都进行手动的转换,但是这样的方式并不可取,所以需要写一个通用的方法,进行操作,
此操作要具有通用性,所以我尝试使用泛型+反射来实现上述需求。
实现代码如下:
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
*
*@classname RequestData
*@author 刘岩松
*@date 2020/6/23 16:31
*/
public class RequestData {
private static Pattern AZ_PATTERN = Pattern.compile("[A-Z]");
private static Pattern UNDERLINE_PATTERN = Pattern.compile("_([a-z])");
public static <T> Map<String, String> generation(T data) {
Map<String, String> result = new LinkedHashMap<>();
Class<?> clazz = data.getClass();
try {
for (Field field : clazz.getDeclaredFields()) {
String key = underline(field.getName()).toUpperCase();
//利用反射执行目标方法获取值
Method method = clazz.getMethod("get" + field.getName().substring(0, 1).toUpperCase().concat(field.getName().substring(1)));
String value = (String) method.invoke(data);
result.put(key, value);
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 将驼峰格式字符串转下划线格式
*
* @param str 待处理字符串
* @author 刘岩松
* @date 2020/6/23 16:55
*/
private static String underline(String str) {
//正则匹配大写字符转成小写并在前面加上下划线
Matcher matcher = AZ_PATTERN.matcher(str);
StringBuffer sb = new StringBuffer(str);
if (matcher.find()) {
sb = new StringBuffer();
//将当前匹配的子串替换成指定字符串,
//并且将替换后的子串及之前到上次匹配的子串之后的字符串添加到StringBuffer对象中
//正则之前的字符和被替换的字符
matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
//把之后的字符串也添加到StringBuffer对象中
matcher.appendTail(sb);
} else {
return sb.toString();
}
return underline(sb.toString());
}
/**
*
*将下划线格式字符串转驼峰格式
*
* @param str string 待处理字符串
* @author 刘岩松
* @date 2020/6/23 16:00
*/
private static String camel(String str) {
//正则匹配下划线及后一个字符,删除下划线并将匹配的字符转成大写
Matcher matcher = UNDERLINE_PATTERN.matcher(str);
StringBuffer sb = new StringBuffer(str);
if (matcher.find()) {
sb = new StringBuffer();
//将当前匹配的子串替换成指定字符串,
//并且将替换后的子串及之前到上次匹配的子串之后的字符串添加到StringBuffer对象中
//正则之前的字符和被替换的字符
matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
//把之后的字符串也添加到StringBuffer对象中
matcher.appendTail(sb);
} else {
return sb.toString();
}
return camel(sb.toString());
}
}
网友评论