是否有一个版本的
BeanUtils.describe(customer)递归调用describe()方法对’客户’的复杂属性.
- class Customer {
- String id;
- Address address;
- }
在这里,我想使用describe方法来检索address属性的内容.
目前,我可以看到类的名称如下:
- {id=123,address=com.test.entities.Address@2a340e}
解决方法
有趣的是,我想使用describe方法来检索嵌套属性的内容,我不明白为什么不这样做.我继续前进,滚过我自己.在这里,你可以打电话:
- Map<String,String> beanMap = BeanUtils.recursiveDescribe(customer);
一些警告.
>我不知道如何在集合中如何使用BeanUtils格式的属性,所以我用“attribute [index]”去了.
>我不知道如何在地图中格式化属性,所以我用“属性[key]”.
>对于名称冲突,优先级是这样的:第一个属性从超级类的字段,然后是类,然后从getter方法加载.
>我没有分析这种方法的性能.如果对象中包含大量集合的对象也包含集合,那么可能会有一些问题.
>这是阿尔法的代码,并不是无法免费的.
>我假设你有最新版本的commons beanutils
此外,fyi,这大概取自于我一直在工作的一个项目,亲切地,java in jails,所以你可以下载它,然后运行:
- Map<String,String[]> beanMap = new SimpleMapper().toMap(customer);
虽然,你会注意到它返回一个String [],而不是String,这可能无法满足你的需要.无论如何,下面的代码应该工作,所以有它!
- 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);
- }
- }
- }