java 通用 JSON 对象转换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3386907/
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
Generic JSON object conversion
提问by Roman
I am de-serializing a JSON object with the ObjectMapperclass in java. I am getting objects of different types (? extends Something) and wanted to know if there is any way to de-serialize them in some generic way. The readValuemethod gets some Class type object of the type of the output object so it is somehow strongly typed.
我正在使用java 中的ObjectMapper类反序列化一个 JSON 对象。我正在获取不同类型的对象(?扩展东西)并想知道是否有任何方法可以以某种通用方式反序列化它们。该readValue方法获取输出对象的类型的一些类型对象,以便它是某种强类型。
回答by StaxMan
Hymanson can take not only type-erased class as target type, but also TypeReference which uses the usual "super type token" pattern. From Hymanson FAQ:
Hymanson 不仅可以将类型擦除的类作为目标类型,还可以将 TypeReference 使用通常的“超类型标记”模式。来自Hyman逊常见问题解答:
List<MyBean> result = mapper.readValue(src, new TypeReference<List<MyBean>>() { });
and this works for all kinds of generic types, not just Maps and Collections. This in case you were thinking of generic types; so that you just have a single class but multiple parametric variations.
这适用于各种泛型类型,而不仅仅是 Maps 和 Collections。以防万一您正在考虑泛型类型;这样你就只有一个类,但有多个参数变化。
But it sounds like maybe what you want is actually support for deserializing polymorphic types; and this is also support (as of Hymanson 1.5, see http://wiki.fasterxml.com/HymansonPolymorphicDeserialization).
但听起来也许您真正想要的是支持反序列化多态类型;这也是支持(从 Hymanson 1.5 开始,请参阅http://wiki.fasterxml.com/HymansonPolymorphicDeserialization)。
EDIT: given sample classes in the other answer, Hymanson way would be to do:
编辑:给出另一个答案中的示例类,Hyman逊的方法是:
import org.codehaus.Hymanson.annotate.JsonTypeInfo;
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS)
public abstract class Message
{
protected Message(){ }
}
and deserialize by:
并通过以下方式反序列化:
Message msg = objectMapper.readValue(json, Message.class);
to get any sub-class of Message. And serialize using 'objectMapper.writeValue();'
获取 Message 的任何子类。并使用 'objectMapper.writeValue();' 进行序列化
回答by Thierry-Dimitri Roy
Have you tried JSON in Java?
回答by Greg
I have been using Json-lib library to accomplish this goal and was quite pleased with the results. Have look at the library examples http://json-lib.sourceforge.net/You can register custom morphers that would transform nested elements of json into proper classes. I was able to get pretty complicated structures from json to java and access all nested fields.
我一直在使用 Json-lib 库来实现这个目标,并且对结果非常满意。查看库示例http://json-lib.sourceforge.net/您可以注册自定义变形器,将 json 的嵌套元素转换为适当的类。我能够从 json 到 java 获得非常复杂的结构并访问所有嵌套字段。
Hope it helps
希望能帮助到你
回答by Roman
Here is an answer I came to:
这是我得到的答案:
First of all I have switched from ObjectMapperto Gson. Define an abstract class and an enum of types:
首先,我已经从ObjectMapper切换到Gson。定义一个抽象类和一个枚举类型:
public abstract class Message {
private MessageType type;
protected Message(){
type = setType();
}
protected abstract MessageType setType();
public MessageType getType() {
return type;
}
public void setType(MessageType type) {
this.type = type;
}
}
public enum MessageType {
PRESENCE(PresenceMessage.class),
TEXT(TextMessage.class);
private Class<? extends Message> clazz;
private MessageType(Class<? extends Message> clazz){
this.clazz = clazz;
}
public Class<? extends Message> getClazz() {
return clazz;
}
}
Every class that extends the Message is the actual one we are sending over Json. It has to implement the getType() method.
每个扩展 Message 的类都是我们通过 Json 发送的实际类。它必须实现 getType() 方法。
So when desirializing just use that code :
因此,在反序列化时只需使用该代码:
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(get.getResponseBodyAsStream(),"UTF-8"));
while ((line = reader.readLine()) != null){
builder.append(line);
}
if (clazz == Message.class){
String string = builder.toString();
Message message = gson.fromJson(string,Message.class);
if (message.getType() == null)
throw new IllegalStateException("Could not de-serialize message " + builder.toString() );
return (T)gson.fromJson(string,message.getType().getClazz());
}
I hope you can fill the missing parts by yourself.
我希望你能自己填补缺失的部分。

