递归遍历获取复杂对象中所有目标属性的值(二)
在[利用递归遍历获取Java复杂对象(对象的属性仍是对象//list/map)中指定属性的值(一)][Java_list_map]中我写了递归遍历复杂对象中目标属性,找到第一个目标属性则退出遍历。现在有遇到要遍历复杂对象中所有目标属性的值。且指定了属性所在类的类名、属性类型、属性名(当然也可以不指定这些,因为我是业务需要)。另外例子对属性为List或者Map的属性的遍历做了一定改动。
现在贴代码如下(如果各位同仁发现bug,望留言告知,多谢):
两个BO类:
public class PCodeTransDefPO implements Serializable {
/**
*
*/
private static final long serialVersionUID = -2806783975707171326L;
private String seqNo;
private String srcSysCode;
private String destSysCode;
private String transColumnName;
private String srcCodeVal;
private String destCodeVal;
private Timestamp procTimestamp;
.........//省略了setter和getter方法
}
class TestClass{
private PCodeTransDefPO PCodeTransDefPO;
private List<PCodeTransDefPO> arrayList = new ArrayList<>();
private Map<String,PCodeTransDefPO> hashMap = new HashMap<>();
public com.newcore.pcms.common.support.codetrans.models.po.pcms.PCodeTransDefPO getPCodeTransDefPO() {
return PCodeTransDefPO;
}
public void setPCodeTransDefPO(com.newcore.pcms.common.support.codetrans.models.po.pcms.PCodeTransDefPO PCodeTransDefPO) {
this.PCodeTransDefPO = PCodeTransDefPO;
}
public List<PCodeTransDefPO> getArrayList() {
return arrayList;
}
public void setArrayList(List<PCodeTransDefPO> arrayList) {
this.arrayList = arrayList;
}
public Map<String, PCodeTransDefPO> getHashMap() {
return hashMap;
}
public void setHashMap(Map<String, PCodeTransDefPO> hashMap) {
this.hashMap = hashMap;
}
}
递归类代码如下:
package com.newcore.pcms.common.support.codetrans.codetrans;
import com.newcore.pcms.common.support.codetrans.codetrans.bo.ServiceAttrDictBO;
import com.newcore.pcms.common.support.codetrans.models.po.pcms.PCodeTransDefPO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author: lsl
* @date: 2018/11/29
*/
public class CodeTransHolderUtils {
private static Logger logger = LoggerFactory.getLogger(CodeTransHolderUtils.class);
/**
* 把t中指定attribute属性的值更改为dictCode,并把没有找到dictCode的attribute放到listNotIncludeAttr
* 注意:
* 1、t只能是javaBean,不能是list<BO>或者Map<K,BO>
* 2、t中的属性类型不能是以下类型:Set、List<Map<K,V>、Map<K,List<BO>>
* 3、t中的属性类型可以是BO、数组、List<BO>、Map<K,BO>
* 4、属性名一定要规范,比如private PCodeTransDefPO pCodeTransDefPO(不规范),这样利用反射找不到getter方法,应该改成codeTransDefPO或者PCodeTransDefPO
*/
public static <T> void ergodicObject(String srcSysCode, String destSysCode, String forwardFlag, T t, String attrClass, String attrType, String attribute, List<String> listNotIncludeAttr, String dictCode) {
String classType = t.getClass().getTypeName();
boolean sunFlag = classType.startsWith("java.") || classType.startsWith("javax.") || classType.startsWith("org.");
if (t == null || checkObjectIsSysType(t) || sunFlag) {
//如果object是null/基本数据类型,或者是sun公司提供的系统类,则不需要在递归调用
return;
}
Class clazz = t.getClass();
String className = t.getClass().getSimpleName();
String srcCodeVal = "";
Field[] fields = clazz.getDeclaredFields();
try {
for (Field field : fields) {
field.setAccessible(true);
String proType = field.getGenericType().toString();
String attrShortName = field.getName();
if (attrClass.equals(className) && attrType.equals("String") && attribute.equals(attrShortName)) {
// 获取object中是字典属性的值,并从数据库查询目标系统字典值,
// 如果查询到目标系统字典值,把object中的字典属性值修改成目标系统的字典值,
// 如果没有查询到目标系统的字典值,则把属性名添加到listNotIncludeAttr
//TODO 目前暂只支持字典属性类型为String类型
srcCodeVal = (String) field.get(t);
String destCodeVal = "";
if ("true".equals(forwardFlag)) {//调用正向码值转换方法
// destCodeVal = CodeTransDefTools.queryOneByCodeTypeAndDestSys(srcCodeVal, dictCode, srcSysCode, destSysCode);
destCodeVal = "ccc333";
} else if ("false".equals(forwardFlag)) {//调用反向码值转换方法
//TODO
} else {
logger.info("数据库中存储该服务的forwardFlag不正确,正确应该是(true/false),实际是forwardFlag=" + forwardFlag);
}
if (destCodeVal != null && !"".equals(destCodeVal)) {
field.set(t, destCodeVal);
} else {
listNotIncludeAttr.add(attribute);
logger.info("在目标系统" + destSysCode + "中,没有找到源系统" + srcSysCode + "中属性是" + attribute + "对应的字典" + dictCode + ",找到的字典值是:" + destCodeVal);
}
} else if ("byte".equals(proType) || "short".equals(proType) || "int".equals(proType) || "long".equals(proType) || "double".equals(proType) || "float".equals(proType) || "boolean".equals(proType)) {
//属性是基本类型跳过
continue;
} else if ("class java.lang.Byte".equals(proType) || "class java.lang.Short".equals(proType) || "class java.lang.Integer".equals(proType) || "class java.lang.Long".equals(proType) || "class java.lang.Double".equals(proType) || "class java.lang.Float".equals(proType) || "class java.lang.Boolean".equals(proType) || ("class java.lang.String".equals(proType) && !attribute.equals(attrShortName))) {
//属性是包装类跳过
continue;
} else if (isList(field)) {
//对List/ArrayList类型的属性遍历
try {
PropertyDescriptor descriptor = new PropertyDescriptor(field.getName(), clazz);
Method method = descriptor.getReadMethod();
List list = (List) method.invoke(t);
if (list != null && list.size() > 0) {
for (Object obj : list){
// 递归
ergodicObject(srcSysCode, destSysCode, forwardFlag, obj, attrClass, attrType, attribute, listNotIncludeAttr, dictCode);
}
}
} catch (IntrospectionException e) {
logger.info(e.getMessage());
} catch (InvocationTargetException e) {
logger.info(e.getMessage());
}
}else if(isMap(field)){
//对Map/HashMap类型的属性遍历
try {
PropertyDescriptor descriptor = new PropertyDescriptor(field.getName(), clazz);
Method method = descriptor.getReadMethod();
Map map = (Map) method.invoke(t);
if (map != null && map.size() > 0) {
for (Object obj : map.values()) {
// 递归
ergodicObject(srcSysCode, destSysCode, forwardFlag, obj, attrClass, attrType, attribute, listNotIncludeAttr, dictCode);
}
}
} catch (IntrospectionException e) {
logger.info(e.getMessage());
} catch (InvocationTargetException e) {
logger.info(e.getMessage());
}
} else if (field.getType().isArray()) {
//属性是数组类型则遍历
field.setAccessible(true);
Object[] objArr = (Object[]) field.get(t);
if (objArr != null && objArr.length > 0) {
for (Object arr : objArr) {
//递归
ergodicObject(srcSysCode, destSysCode, forwardFlag, arr, attrClass, attrType, attribute, listNotIncludeAttr, dictCode);
}
}
} else {
//class类型的遍历
try {
PropertyDescriptor descriptor = new PropertyDescriptor(field.getName(), clazz);
Method method = descriptor.getReadMethod();
Object obj = method.invoke(t);
if (obj != null) {
//递归
ergodicObject(srcSysCode, destSysCode, forwardFlag, obj, attrClass, attrType, attribute, listNotIncludeAttr, dictCode);
} else {
continue;
}
} catch (IntrospectionException e) {
logger.info(e.getMessage());
} catch (InvocationTargetException e) {
logger.info(e.getMessage());
}
}
}
} catch (IllegalAccessException e) {
logger.info(e.getMessage());
}
}
/**
* 判断是否是List或者ArrayList
* @param field
* @return
*/
public static boolean isList(Field field){
boolean flag = false;
String simpleName = field.getType().getSimpleName();
if ("List".equals(simpleName) || "ArrayList".equals(simpleName)){
flag = true;
}
return flag;
}
/**
* 判断是否是Map或者HashMap
* @param field
* @return
*/
public static boolean isMap(Field field){
boolean flag = false;
String simpleName = field.getType().getSimpleName();
if ("Map".equals(simpleName) || "HashMap".equals(simpleName)){
flag = true;
}
return flag;
}
/**
* 检查object是否为java的基本数据类型
*
* @param object
* @return
*/
public static boolean checkObjectIsSysType(Object object) {
String objType = object.getClass().toString();
if ("byte".equals(objType) || "short".equals(objType) || "int".equals(objType) || "long".equals(objType) || "double".equals(objType) || "float".equals(objType) || "boolean".equals(objType)) {
return true;
} else {
return false;
}
}
//==============================================================================================
public static void main(String[] args) {
PCodeTransDefPO bo = new PCodeTransDefPO();
bo.setSrcSysCode("BO000");
PCodeTransDefPO boList = new PCodeTransDefPO();
boList.setSrcSysCode("BOList");
PCodeTransDefPO boMap = new PCodeTransDefPO();
boMap.setSrcSysCode("BOMap");
TestClass testClass = new TestClass();
List<PCodeTransDefPO> list = new ArrayList<>();
list.add(boList);
Map<String,PCodeTransDefPO> map = new HashMap<>();
map.put("11",boMap);
testClass.setPCodeTransDefPO(bo);
testClass.setArrayList(list);
testClass.setHashMap(map);
List<String> notAttrList = new ArrayList<>();
// loopObject(testClass);
System.out.println("修改前,BO中的目标属性:"+ testClass.getPCodeTransDefPO().getSrcSysCode());
System.out.println("修改前,List中的目标属性:"+ testClass.getArrayList().get(0).getSrcSysCode());
System.out.println("修改前,Map中的目标属性:"+ testClass.getHashMap().get("11").getSrcSysCode());
ergodicObject("srcsys","destsys","true",testClass,"PCodeTransDefPO","String","srcSysCode",notAttrList,"sysDictCode");
System.out.println("修改后,BO中的目标属性:"+ testClass.getPCodeTransDefPO().getSrcSysCode());
System.out.println("修改后,List中的目标属性:"+ testClass.getArrayList().get(0).getSrcSysCode());
System.out.println("修改后,Map中的目标属性:"+ testClass.getHashMap().get("11").getSrcSysCode());
}
}
class TestClass{
private PCodeTransDefPO PCodeTransDefPO;
private List<PCodeTransDefPO> arrayList = new ArrayList<>();
private Map<String,PCodeTransDefPO> hashMap = new HashMap<>();
public com.newcore.pcms.common.support.codetrans.models.po.pcms.PCodeTransDefPO getPCodeTransDefPO() {
return PCodeTransDefPO;
}
public void setPCodeTransDefPO(com.newcore.pcms.common.support.codetrans.models.po.pcms.PCodeTransDefPO PCodeTransDefPO) {
this.PCodeTransDefPO = PCodeTransDefPO;
}
public List<PCodeTransDefPO> getArrayList() {
return arrayList;
}
public void setArrayList(List<PCodeTransDefPO> arrayList) {
this.arrayList = arrayList;
}
public Map<String, PCodeTransDefPO> getHashMap() {
return hashMap;
}
public void setHashMap(Map<String, PCodeTransDefPO> hashMap) {
this.hashMap = hashMap;
}
}
还没有评论,来说两句吧...