2

我正在使用 java 中的ObjectMapper类反序列化 JSON 对象。我得到了不同类型的对象(?扩展了一些东西),并想知道是否有任何方法可以以某种通用方式对它们进行反序列化。readValue方法获取输出对象类型的一些 Class 类型对象,因此它在某种程度上是强类型的。

4

5 回答 5

7

Jackson 不仅可以将类型擦除的类作为目标类型,还可以使用通常的“超级类型令牌”模式的 TypeReference。来自杰克逊常见问题解答:

List<MyBean> result = mapper.readValue(src, new TypeReference<List<MyBean>>() { });

这适用于各种泛型类型,而不仅仅是 Maps 和 Collections。如果您正在考虑泛型类型,请这样做;这样您就只有一个类但有多个参数变体。

但听起来你想要的实际上是支持反序列化多态类型;这也是支持(从杰克逊 1.5 开始,请参阅http://wiki.fasterxml.com/JacksonPolymorphicDeserialization)。

编辑:给定另一个答案中的示例类,杰克逊的方法是:

import org.codehaus.jackson.annotate.JsonTypeInfo;

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS)
public abstract class Message
{
    protected Message(){ }
}

并通过以下方式反序列化:

Message msg = objectMapper.readValue(json, Message.class);

获取消息的任何子类。并使用 'objectMapper.writeValue();' 进行序列化

于 2010-08-02T19:37:14.023 回答
0

我一直在使用 Json-lib 库来实现这个目标,并且对结果非常满意。查看库示例http://json-lib.sourceforge.net/ 您可以注册自定义变形器,将 json 的嵌套元素转换为适当的类。我能够获得从 json 到 java 的非常复杂的结构并访问所有嵌套字段。

希望能帮助到你

于 2010-08-02T13:17:54.887 回答
0

这是我得到的答案:

首先,我已经从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;
   }
}

每个扩展 Message 的类都是我们通过 Json 发送的实际类。它必须实现 getType() 方法。

因此,在反序列化时只需使用该代码:

    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());
    }

我希望你能自己填补缺失的部分。

于 2010-08-03T09:25:37.400 回答
0

在 Java 中尝试过 JSON吗?

于 2010-08-02T13:11:55.963 回答
-3

GSON老兄。 https://sites.google.com/site/gson/gson-user-guide#TOC-Object-Examples

于 2012-04-20T14:29:21.570 回答