Java introspection: object to map

后端 未结 7 976
无人及你
无人及你 2020-11-28 05:52

I have a Java object obj that has attributes obj.attr1, obj.attr2 etc. The attributes are possibly accessed through an extra level of

7条回答
  •  死守一世寂寞
    2020-11-28 06:12

    None of these work for nested properties, object mapper does a fair job except that you have to set all values on all fields you want to see in map and even then you cannot avoid/ignore objects own @Json annotations easily in ObjectMapper basically skip some of the properties. So unfortunately, you have to do something like the following, it is only a draft to just give an idea.

    /*
         * returns fields that have getter/setters including nested fields as
         * field0, objA.field1, objA.objB.field2, ... 
         * to take care of recursive duplicates, 
         * simply use a set to track which classes
         * have already been traversed
         */
        public static void getBeanUtilsNestedFields(String prefix, 
                Class clazz,  List nestedFieldNames) throws Exception {
            PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(clazz);
            for(PropertyDescriptor descr : descriptors){
                // if you want values, use: descr.getValue(attributeName)
                if(descr.getPropertyType().getName().equals("java.lang.Class")){
                    continue;
                }
                // a primitive, a CharSequence(String), Number, Date, URI, URL, Locale, Class, or corresponding array
                // or add more like UUID or other types
                if(!BeanUtils.isSimpleProperty(descr.getPropertyType())){
                    Field collectionfield = clazz.getDeclaredField(descr.getName());
                    if(collectionfield.getGenericType() instanceof ParameterizedType){
                        ParameterizedType integerListType = (ParameterizedType) collectionfield.getGenericType();
                        Class actualClazz = (Class) integerListType.getActualTypeArguments()[0];
                        getBeanUtilsNestedFields(descr.getName(), actualClazz, nestedFieldNames);
                    }
                    else{   // or a complex custom type to get nested fields
                        getBeanUtilsNestedFields(descr.getName(), descr.getPropertyType(), nestedFieldNames);
                    }
                }
                else{
                    nestedFieldNames.add(prefix.concat(".").concat(descr.getDisplayName()));
                }
            }
        }
    

提交回复
热议问题