如何将 Java 对象(bean)转换为键值对(反之亦然)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/739689/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert a Java object (bean) to key-value pairs (and vice versa)?
提问by Shahbaz
Say I have a very simple java object that only has some getXXX and setXXX properties. This object is used only to handle values, basically a record or a type-safe (and performant) map. I often need to covert this object to key value pairs (either strings or type safe) or convert from key value pairs to this object.
假设我有一个非常简单的 java 对象,它只有一些 getXXX 和 setXXX 属性。此对象仅用于处理值,基本上是记录或类型安全(和高性能)映射。我经常需要将此对象转换为键值对(字符串或类型安全)或从键值对转换为此对象。
Other than reflection or manually writing code to do this conversion, what is the best way to achieve this?
除了反射或手动编写代码来进行这种转换之外,实现这一目标的最佳方法是什么?
An example might be sending this object over jms, without using the ObjectMessage type (or converting an incoming message to the right kind of object).
一个示例可能是通过 jms 发送此对象,而不使用 ObjectMessage 类型(或将传入消息转换为正确类型的对象)。
采纳答案by Maurice Perry
There is always apache commons beanutilsbut of course it uses reflection under the hood
总是有 apache commons beanutils但当然它在引擎盖下使用反射
回答by Michael Borgwardt
Code generation would be the only other way I can think of. Personally, I'd got with a generally reusable reflection solution (unless that part of the code is absolutely performance-critical). Using JMS sounds like overkill (additional dependency, and that's not even what it's meant for). Besides, it probably uses reflection as well under the hood.
代码生成将是我能想到的唯一其他方式。就我个人而言,我得到了一个通常可重用的反射解决方案(除非代码的那部分绝对是性能关键)。使用 JMS 听起来有点矫枉过正(额外的依赖,这甚至不是它的意思)。此外,它可能也在引擎盖下使用反射。
回答by mjn
JSON, for example using XStream + Jettison, is a simple text format with key value pairs. It is supported for example by the Apache ActiveMQ JMS message broker for Java object exchange with other platforms / languages.
JSON,例如使用 XStream + Jettison,是一种带有键值对的简单文本格式。例如,Apache ActiveMQ JMS 消息代理支持它与其他平台/语言进行 Java 对象交换。
回答by Jon
You could use the Joda framework:
您可以使用 Joda 框架:
and take advantage of JodaProperties. This does stipulate that you create beans in a particular way however, and implement a specific interface. It does then however, allow you to return a property map from a specific class, without reflection. Sample code is here:
并利用 JodaProperties。但是,这确实规定您以特定方式创建 bean,并实现特定接口。但是,它允许您从特定类返回属性映射,而无需反射。示例代码在这里:
http://pbin.oogly.co.uk/listings/viewlistingdetail/0e78eb6c76d071b4e22bbcac748c57
http://pbin.oogly.co.uk/listings/viewlistingdetail/0e78eb6c76d071b4e22bbcac748c57
回答by Scott Stanchfield
My JavaDude Bean Annotation Processor generates code to do this.
我的 JavaDude Bean 注释处理器生成代码来执行此操作。
http://javadude.googlecode.com
http://javadude.googlecode.com
For example:
例如:
@Bean(
createPropertyMap=true,
properties={
@Property(name="name"),
@Property(name="phone", bound=true),
@Property(name="friend", type=Person.class, kind=PropertyKind.LIST)
}
)
public class Person extends PersonGen {}
The above generates superclass PersonGen that includes a createPropertyMap() method that generates a Map for all properties defined using @Bean.
上面生成的超类 PersonGen 包括一个 createPropertyMap() 方法,该方法为使用@Bean 定义的所有属性生成一个 Map。
(Note that I'm changing the API slightly for the next version -- the annotation attribute will be defineCreatePropertyMap=true)
(请注意,我正在为下一个版本稍微更改 API -- 注释属性将为 defineCreatePropertyMap=true)
回答by Thorbj?rn Ravn Andersen
If you do not want to hardcode calls to each getter and setter, reflection is the only way to call these methods (but it is not hard).
如果您不想硬编码对每个 getter 和 setter 的调用,反射是调用这些方法的唯一方法(但这并不难)。
Can you refactor the class in question to use a Properties object to hold the actual data, and let each getter and setter just call get/set on it? Then you have a structure well suited for what you want to do. There is even methods to save and load them in the key-value form.
您能否重构有问题的类以使用 Properties 对象来保存实际数据,并让每个 getter 和 setter 对其调用 get/set?然后你就有了一个非常适合你想做的事情的结构。甚至还有以键值形式保存和加载它们的方法。
回答by Martin K.
You should write a generic transformation Service! Use generics to keep it type free (so you can convert every object to key=>value and back).
你应该写一个通用的转换服务!使用泛型使其类型自由(因此您可以将每个对象转换为 key=>value 并返回)。
What field should be the key? Get that field from the bean and append any other non transient value in a value map.
什么领域应该是关键?从 bean 中获取该字段并将任何其他非瞬态值附加到值映射中。
The way back is pretty easy. Read key(x) and write at first the key and then every list entry back to a new object.
回来的路还算轻松。读取 key(x) 并首先写入 key,然后将每个列表条目写回一个新对象。
You can get the property names of a bean with the apache commons beanutils!
您可以使用apache commons beanutils获取 bean 的属性名称!
回答by Martin K.
The best solution is to use Dozer. You just need something like this in the mapper file:
最好的解决方案是使用 Dozer。你只需要在映射器文件中这样的东西:
<mapping map-id="myTestMapping">
<class-a>org.dozer.vo.map.SomeComplexType</class-a>
<class-b>java.util.Map</class-b>
</mapping>
And that's it, Dozer takes care of the rest!!!
就是这样,Dozer 负责其余的工作!!!
回答by StaxMan
Lots of potential solutions, but let's add just one more. Use Hymanson(JSON processing lib) to do "json-less" conversion, like:
许多潜在的解决方案,但让我们再添加一个。使用Hymanson(JSON 处理库)进行“无 json”转换,例如:
ObjectMapper m = new ObjectMapper();
Map<String,Object> props = m.convertValue(myBean, Map.class);
MyBean anotherBean = m.convertValue(props, MyBean.class);
(this blog entryhas some more examples)
(此博客条目有更多示例)
You can basically convert any compatible types: compatible meaning that if you did convert from type to JSON, and from that JSON to result type, entries would match (if configured properly can also just ignore unrecognized ones).
您基本上可以转换任何兼容类型:兼容意味着如果您确实从类型转换为 JSON,并从该 JSON 转换为结果类型,则条目将匹配(如果配置正确,也可以忽略无法识别的类型)。
Works well for cases one would expect, including Maps, Lists, arrays, primitives, bean-like POJOs.
适用于预期的情况,包括映射、列表、数组、原语、类 bean 的 POJO。
回答by Lars Wunderlich
If it comes to a simple object tree to key value list mapping, where key might be a dotted path description from the object's root element to the leaf being inspected, it's rather obvious that a tree conversion to a key-value list is comparable to an object to xml mapping. Each element within an XML document has a defined position and can be converted into a path. Therefore I took XStreamas a basic and stable conversion tool and replaced the hierarchical driver and writer parts with an own implementation. XStream also comes with a basic path tracking mechanism which - being combined with the other two - strictly leads to a solution being suitable for the task.
如果涉及到简单的对象树到键值列表的映射,其中键可能是从对象的根元素到被检查的叶子的点状路径描述,很明显,将树转换为键值列表与对象到 xml 映射。XML 文档中的每个元素都有一个定义的位置,并且可以转换为路径。因此,我将XStream作为基本且稳定的转换工具,并用自己的实现替换了分层驱动程序和编写器部分。XStream 还带有一个基本的路径跟踪机制 - 与其他两个结合 - 严格地导致适合该任务的解决方案。