Java – recursive BeanUtils describe()

Is there a version of BeanUtils Describe (customer) recursively calls the describe () method to the complex attribute of 'customer'

class Customer {

String id;
Address address;

}

Here, I want to use the describe method to retrieve the contents of the address attribute

At present, I can see the name of the class as follows:

{id=123,address=com.test.entities.Address@2a340e}

Solution

Interestingly, I want to use the describe method to retrieve the contents of nested attributes, and I don't understand why not I moved on and rolled over myself Here, you can call:

Map<String,String> beanMap = BeanUtils.recursiveDescribe(customer);

Some warnings

>I don't know how to use BeanUtils format attributes in the collection, so I use "attribute [index]". > I don't know how to format attributes in the map, so I use "attribute [key]. > For name conflicts, the priority is as follows: the first attribute is from the field of the super class, then the class, and then loaded from the getter method. > I did not analyze the performance of this method If an object that contains a large number of collections also contains collections, there may be some problems. > This is alpha code, not free. > I assume you have the latest version of Commons beautils

In addition, FYI, this is probably from a project I have been working on. Affectionately, Java in sails, so you can download it and run it:

Map<String,String[]> beanMap = new SimpleMapper().toMap(customer);

Although, you will notice that it returns a string [] instead of a string, which may not meet your needs Anyway, the following code should work, so there is it!

public class BeanUtils {
    public static Map<String,String> recursiveDescribe(Object object) {
        Set cache = new HashSet();
        return recursiveDescribe(object,null,cache);
    }

    private static Map<String,String> recursiveDescribe(Object object,String prefix,Set cache) {
        if (object == null || cache.contains(object)) return Collections.EMPTY_MAP;
        cache.add(object);
        prefix = (prefix != null) ? prefix + "." : "";

        Map<String,String> beanMap = new TreeMap<String,String>();

        Map<String,Object> properties = getProperties(object);
        for (String property : properties.keySet()) {
            Object value = properties.get(property);
            try {
                if (value == null) {
                    //ignore nulls
                } else if (Collection.class.isAssignableFrom(value.getClass())) {
                    beanMap.putAll(convertAll((Collection) value,prefix + property,cache));
                } else if (value.getClass().isArray()) {
                    beanMap.putAll(convertAll(Arrays.asList((Object[]) value),cache));
                } else if (Map.class.isAssignableFrom(value.getClass())) {
                    beanMap.putAll(convertMap((Map) value,cache));
                } else {
                    beanMap.putAll(convertObject(value,cache));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return beanMap;
    }

    private static Map<String,Object> getProperties(Object object) {
        Map<String,Object> propertyMap = getFields(object);
        //getters take precedence in case of any name collisions
        propertyMap.putAll(getGetterMethods(object));
        return propertyMap;
    }

    private static Map<String,Object> getGetterMethods(Object object) {
        Map<String,Object> result = new HashMap<String,Object>();
        BeanInfo info;
        try {
            info = Introspector.getBeanInfo(object.getClass());
            for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
                Method reader = pd.getReadMethod();
                if (reader != null) {
                    String name = pd.getName();
                    if (!"class".equals(name)) {
                        try {
                            Object value = reader.invoke(object);
                            result.put(name,value);
                        } catch (Exception e) {
                            //you can choose to do something here
                        }
                    }
                }
            }
        } catch (IntrospectionException e) {
            //you can choose to do something here
        } finally {
            return result;
        }

    }

    private static Map<String,Object> getFields(Object object) {
        return getFields(object,object.getClass());
    }

    private static Map<String,Object> getFields(Object object,Class<?> classType) {
        Map<String,Object>();

        Class superClass = classType.getSuperclass();
        if (superClass != null) result.putAll(getFields(object,superClass));

        //get public fields only
        Field[] fields = classType.getFields();
        for (Field field : fields) {
            try {
                result.put(field.getName(),field.get(object));
            } catch (illegalaccessexception e) {
                //you can choose to do something here
            }
        }
        return result;
    }

    private static Map<String,String> convertAll(Collection<Object> values,String key,Set cache) {
        Map<String,String> valuesMap = new HashMap<String,String>();
        Object[] valArray = values.toArray();
        for (int i = 0; i < valArray.length; i++) {
            Object value = valArray[i];
            if (value != null) valuesMap.putAll(convertObject(value,key + "[" + i + "]",cache));
        }
        return valuesMap;
    }

    private static Map<String,String> convertMap(Map<Object,Object> values,String>();
        for (Object thisKey : values.keySet()) {
            Object value = values.get(thisKey);
            if (value != null) valuesMap.putAll(convertObject(value,key + "[" + thisKey + "]",cache));
        }
        return valuesMap;
    }

    private static ConvertUtilsBean converter = BeanUtilsBean.getInstance().getConvertUtils();

    private static Map<String,String> convertObject(Object value,Set cache) {
        //if this type has a registered converted,then get the string and return
        if (converter.lookup(value.getClass()) != null) {
            String stringValue = converter.convert(value);
            Map<String,String> valueMap = new HashMap<String,String>();
            valueMap.put(key,stringValue);
            return valueMap;
        } else {
            //otherwise,treat it as a nested bean that needs to be described itself
            return recursiveDescribe(value,key,cache);
        }
    }
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>