项目不同系统相互调用时,有些是直接根据接口组报文,或者先根据对方的接口组实体类,在转换成报文。如果需要通过后者先组实体类的方式,接口调用过多时或者对方接口嵌套比较深,那么在组实体类时会导入很多类,程序界面比较臃肿。那么就可以通过反射来组装请求类。
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ReflectUtil {
private static Logger logger = LoggerFactory.getLogger(ReflectUtil.class);
public static Map<String, String> Map_AllClassPath = new HashMap<String, String>();
public static Map<String, Class> Map_AllClassObj = new HashMap<String, Class>();
/**
*
* @param map 类属性与值的键值对
* @param packPath 包名
* @param objType 要获取的反射对象类名
* @return
* @throws Exception
*/
public Object getESBReqObj(Map<String, Object> map, String packPath, String objType) throws Exception {
Class<?> clazz = Class.forName(packPath);
// 获取内部类
Class<?>[] innerClazz = clazz.getDeclaredClasses();
// 用于反射各级子类使用,存放请求类中所以子类类名
List<String> sonClsName = new ArrayList<String>();
for (Class<?> cls : innerClazz) {
String clsName = cls.getName();
// 获取子类名称
int rmkindex = clsName.indexOf("$") + 1;
String clsName1 = clsName.substring(rmkindex);
sonClsName.add(clsName.substring(rmkindex));
Map_AllClassPath.put(clsName1, clsName);
Map_AllClassObj.put(clsName1, cls);
}
// 判断入参类名
if (Map_AllClassPath.containsKey(objType)) {
Object obj = refToObject(map, Map_AllClassPath.get(objType));
return obj;
} else {
logger.error("在待反射类中不存在" + objType + "此类");
}
return objType;
}
/**
*
* @param map 属性值
* @param className 内部类类名
* @return
* @throws Exception
*/
private Object refToObject(Map<String, Object> map, String className) throws Exception {
Class<?> c = Class.forName(className);
Object obj = c.newInstance();
Field[] files = c.getDeclaredFields();
// 存放上级类对象
Map<String, Object> Map_TransMap = new HashMap<String, Object>();
// 获取set方法赋值
for (Field field : files) {
// 获取变量名称
String fpath = field.toString();
String fname = fpath.substring(fpath.lastIndexOf(".") + 1);
// 获取变量类型
Class<?> ftype = field.getType();
// 属性类型名称,除去前缀"class"
String ftypenm = ftype.toString().substring(6);
// 与接口对应的字段名称,除去前缀local
String ffname = fname.substring(5);
// 处理list对象
if ("class java.util.ArrayList".equals(ftype.toString())) {
Type listType = c.getDeclaredField(fname).getGenericType();
String listTypeNm = listType.toString();
// 获取list泛型类型
int startIndex = listTypeNm.indexOf("<") + 1;
int endIndex = listTypeNm.indexOf(">");
String listInnerTy = listTypeNm.substring(startIndex, endIndex);
if (Map_AllClassPath.containsValue(listInnerTy)) {
// 存放转换后的结果对象
List<Object> innerObjList = new ArrayList<Object>();
for (Map<String, Object> innerMap : (List<Map>) map.get(ffname)) {
Object innerSonObj = refToObject(innerMap, listInnerTy);
innerObjList.add(innerSonObj);
}
// 移除以转换的类
Map_AllClassPath.remove(files);
Map_TransMap.put(fname, innerObjList);
}
} else if (Map_AllClassPath.containsKey(ftypenm)) {
Map<String, Object> tempMap = new HashMap<String, Object>();
if (map.containsKey(ffname)) {
tempMap = (Map<String, Object>) map.get(ffname);
} else {
tempMap = map;
}
Object sonObj = refToObject(tempMap, ftypenm);
Map_TransMap.put(fname, sonObj);
Map_AllClassPath.remove(files);
} else if (map.containsKey(ffname)) {
Method method = c.getMethod(
"set" + ffname.substring(0, 1).toUpperCase() + ffname.substring(1, ffname.length()), ftype);
logger.info("类属性类型:" + ffname + "---" + ftype + "---" + (map.get(ffname)).getClass());
if (field.getType().isAssignableFrom(String.class)) {
logger.info(ffname + "String类型属性");
if (map.get(ffname).getClass().isAssignableFrom(Integer.class)
|| map.get(ffname).getClass().isAssignableFrom(Long.class)
|| map.get(ffname).getClass().isAssignableFrom(Float.class)) {
method.invoke(obj, map.get(ffname).toString());
} else {
method.invoke(obj, map.get(ffname));
logger.info(ffname + "反射成功");
}
} else if (field.getType().isAssignableFrom(Double.class)
|| field.getType().isAssignableFrom(double.class)) {
logger.info(ffname + "Double类型属性");
if (map.get(ffname).getClass().isAssignableFrom(Integer.class)
|| map.get(ffname).getClass().isAssignableFrom(Long.class)
|| map.get(ffname).getClass().isAssignableFrom(String.class)
|| map.get(ffname).getClass().isAssignableFrom(Float.class)) {
method.invoke(obj, (Double) Double.parseDouble(map.get(ffname).toString()));
logger.info(ffname + "反射成功");
}
} else {
Object object = (Object) map.get(ffname);
if (object instanceof ArrayList) {
ArrayList list = (ArrayList) object;
if (list.size() > 0) {
method.invoke(obj, map.get(ffname));
}
} else {
method.invoke(obj, map.get(ffname));
}
}
}
if (!Map_TransMap.isEmpty()) {
logger.info("开始组装上层对象");
for (Map.Entry<String, Object> emap : Map_TransMap.entrySet()) {
String ename = emap.getKey().substring(5);
Class etype = emap.getValue().getClass();
Method method = c.getMethod(
"set" + ename.substring(0, 1).toUpperCase() + ename.substring(1, ename.length()), etype);
method.invoke(obj, Map_TransMap.get(emap.getKey()));
logger.info("上层对象组装成功");
}
}
}
return obj;
}
}
关于入参map的要求,按照接口层级组装map节点即可