使用基于JSON类型的Jackson进行反序列化

时间:2017-05-21 08:35:01

标签: java json jackson

我有一个JSON有效负载,我试图使用Jackson进行反序列化,如下所示:

{
  "id": "12",
  "type": "foo",
  "created": "2011-03-20T31:12:00+00:00",
  "data": {
    "object": {
        objectId: 1
        fizz: "bizz"
    }
}

有3种不同的"类型"响应可能{foo, bar, foobar}并且,根据有效负载中的哪种类型,"object"节点下面会有不同的数据(例如foo类型有fizz)。我试图编写一些将检测类型的反序列化器,并输出包含class内容的"object"。我基本上可以忽略id和创建的字段。类的类型如下:

public interface ObjectType {
   String getId()
}

public class Foo implements ObjectType {
   String objectId;
   String fizz;

   String getId() {
      return objectId;
   }
}

public class Bar implements ObjectType {
   String objectId;
   String test;

   String getId() {
      return objectId;
   }
}

public class FooBar implements ObjectType {
   String objectId;
   String something;

   String getId() {
      return objectId;
   }
}

杰克逊最简单的方法是什么?

1 个答案:

答案 0 :(得分:0)

一种可能性是编写自定义反序列化器。存根实现可以如下:

class ContainerDeserializer extends StdDeserializer<Container> {

    private static final long serialVersionUID = 8976140492203602443L;

    public ContainerDeserializer() {
        this(null);
    }

    public ContainerDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public Container deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        int id = (Integer) ((IntNode) node.get("id")).numberValue();
        String type = node.get("type").asText();
        ObjectType obj;
        String objId = node.get("obj").get("objectId").asText();
        switch (type) {
        case "foo":
            String fizz = node.get("obj").get("fizz").asText();
            obj = new Foo(objId, fizz);
            break;
        case "bar":
            String test = node.get("obj").get("test").asText();
            obj = new Bar(objId, test);
            break;
        default:
            // Error handling
            obj = null;

        }

        return new Container(id, type, obj);
    }
}

对于实现,我假设您有以下Container类:

class Container {
    private String type;
    private int id;
    private ObjectType obj;

    public Container(int id, String type, ObjectType obj) {
        this.id = id;
        this.type = type;
        this.obj = obj;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public ObjectType getObj() {
        return obj;
    }

    public void setObj(ObjectType obj) {
        this.obj = obj;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

}

我还为你的Foo和Bar课程添加了getter和setter。

现在只需用

注册Deserializer
ObjectMapper om = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Container.class, new ContainerDeserializer());
om.registerModule(module);

并使用

反序列化
om.readValue(test, Container.class);