反射构建类

项目不同系统相互调用时,有些是直接根据接口组报文,或者先根据对方的接口组实体类,在转换成报文。如果需要通过后者先组实体类的方式,接口调用过多时或者对方接口嵌套比较深,那么在组实体类时会导入很多类,程序界面比较臃肿。那么就可以通过反射来组装请求类。


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节点即可
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章