如何使用Jackson将JSON数组中的子文档表示为Java Collection?

时间:2014-07-11 10:16:15

标签: java json jackson deserialization

我很高兴知道使用Jackson Annotations将从Salesforce收到的以下JSON响应反序列化为Java对象的最佳方法。

"records": [
  {
      "attributes": {
        "type": "Lead",
        "url": "/services/data/v30.0/sobjects/Lead/00Qi000000Jr44XEAR"
      },
      "Id": "00Qi000000Jr44XEAR",
      "Name": "Kristen Akin",
      "Address": {
          "city": null,
          "country": "USA",
          "state": "CA",
          "stateCode": null,
          "street": null
      },
      "Phone": "(434) 369-3100",
  },
  {
      "attributes": {
      "type": "Lead",
      "url": "/services/data/v30.0/sobjects/Lead/00Qi000000Jugv2EAB"
      },
      "Id": "00Qi000000Jugv2EAB",
      "Name": "Sarah Jones",
      "Address": {
        "city": null,
        "country": null,
        "state": "CA",
        "stateCode": null,
        "street": null
      },
      "Phone": "(408) 338-6066",
  }
]}

上面的JSON响应是一个包含2个元素的数组。我想使用Jackson将这个JSON结构表示为Java Collection,如:

@JsonProperty("records")
ArrayList<LinkedHashMap<?, ?>> recordList

上述对象表示反序列化JSON响应并在HashMap中表示为键值对,但问题是表示“属性”和“地址”子文档。在上面的HashMap中,它们的值被表示为相应的JSON子文档,而我更愿意将Attributes子文档映射到Attribute对象,类似地,Address子文档映射到HashMap中的Address对象,如:

Key            Value
attributes     <Attributes> object
Id             00Qi000000Jr44XEAR
.....
Address        <Address> object
Phone          (434) 369-3100

在进行一些Google搜索后,我想我可能必须使用此link中提到的@JsonTypeInfo和@JsonSubTypes属性。

但是,我无法想象如何在这个特定场景中使用这些注释。感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

如果JSON输入的结构是完全动态的,您可以将其读作JsonNode甚至是Map。有关详细信息,请参阅此link

如果要将JSON映射到java类,但不了解编译类型中的所有属性,则可以使用the @JsonAnyGetter/@JsonAnySetter annotations。以下是基于JSON的示例,该示例在内部映射中存储Address类的未知属性。

public class JacksonMapping {
    public static final String JSON = "...";

    public static class Attributes {
        public String type;
        public URI url;
    }

    public static class Address {
        public String city;
        public String country;
        public String state;
        public Integer stateCode;
        public String street;
        private final Map<String, Object> otherAttributes = new HashMap<>();

        @JsonAnySetter
        public void setProperty(String name, Object value) {
            otherAttributes.put(name, value);
        }

        @JsonAnyGetter
        public Map<String, Object> getOtherAttributes() {
            return otherAttributes;
        }
    }

    public static class Record {
        @JsonProperty("Id")
        public String id;
        @JsonProperty("Name")
        public String name;
        public Attributes attributes;
        @JsonProperty("Address")
        public Address address;
        @JsonProperty("Phone")
        public String phone;
    }

    public static class RecordList {
        public List<Record> records;
    }

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        RecordList recordList = mapper.readValue(JSON, RecordList.class);
        System.out.println(mapper.writerWithDefaultPrettyPrinter()
                .writeValueAsString(recordList));
    }

}

我还可以尝试在工具的帮助下从JSON生成java对象。例如,这一个:http://www.jsonschema2pojo.org