【发布时间】:2014-10-26 23:39:24
【问题描述】:
我坚持将Java Bean 转换为Map。互联网上有很多资源,但不幸的是,它们都将简单的 bean 转换为 Maps。我的更广泛一些。
有一个简化的例子:
public class MyBean {
private String firstName;
private String lastName;
private MyHomeAddress homeAddress;
private int age;
// getters & setters
}
我的意思是产生Map<String, Object>,在这种情况下,以下条件是正确的:
map.containsKey("firstName")
map.containsKey("lastName")
map.containsKey("homeAddress.street") // street is String
map.containsKey("homeAddress.number") // number is int
map.containsKey("homeAddress.city") // city is String
map.containsKey("homeAddress.zipcode") // zipcode is String
map.containsKey("age")
我尝试过使用Apache Commons BeanUtils。 BeanUtils#describe(Object) 和 BeanMap(Object) 两种方法都会生成一个“深度”为 1 的 Map(我的意思是只有 "homeAddress" 键,将 MyHomeAddress 对象作为值)。我的方法应该越来越深入地输入对象,直到它遇到原始类型(或字符串),然后它应该停止挖掘并插入密钥,即"order.customer.contactInfo.home"。
所以,我的问题是:如何轻松完成(或者是否已经存在可以让我这样做的项目)?
更新
我已扩展 Radiodef 答案以包括集合、地图数组和枚举:
private static boolean isValue(Object value) {
final Class<?> clazz = value.getClass();
if (value == null ||
valueClasses.contains(clazz) ||
Collection.class.isAssignableFrom(clazz) ||
Map.class.isAssignableFrom(clazz) ||
value.getClass().isArray() ||
value.getClass().isEnum()) {
return true;
}
return false;
}
【问题讨论】:
-
您可能不是指“原始”,因为
String不是原始的(它扩展了Object)。所以你需要一种方法来告诉算法要遍历哪些类,以及将哪些类作为值,所以如果没有某种配置(可能使用注释),可能没有办法做到这一点。跨度> -
这可以通过反射和递归来完成,您几乎可以肯定必须自己编写。请注意,目前该问题将被关闭,因为要求图书馆推荐是题外话。
-
Tonio,Radiodef - 感谢您的建议,我已经编辑了我的帖子。
-
嗨,通常我会遇到想将 bean 映射到传输对象的情况。当创建页面对象以进行显示或以某种方式将结构从一种更改为另一种时,通常会出现这种情况。在这些情况下,我使用 Dozer 或 ModelMapper 之类的东西,它们允许使用各种方法进行映射,例如 xml、api 或基于注释。
-
@TechTrip 感谢您提到 Dozer 和 ModelMapper。不幸的是,它们都不允许 JavaBean 以 Map 结尾。无论如何,我刚刚读过它们,它们似乎是非常有趣的工具。
标签: java javabeans apache-commons