递归遍历获取复杂对象中所有目标属性的值(二)

       在利用递归遍历获取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;
    }


}

猜你喜欢

转载自blog.csdn.net/dhklsl/article/details/84751008