Serialization 在Java中使用Jackson将JSON数组反序列化为映射

Serialization 在Java中使用Jackson将JSON数组反序列化为映射,serialization,map,jackson,deserialization,arrays,Serialization,Map,Jackson,Deserialization,Arrays,我正在使用fasterXML的Jackson(v2.3.3)库对自定义类进行反序列化。该类定义如下: public class Person { private String name; private Map<String, Person> children; // lots of other fields of different types with no issues } (许多字段(如子字段)是可选的,当为空时不会序列化) 到目前为止,我一直将子对象存储在

我正在使用fasterXML的Jackson(v2.3.3)库对自定义类进行反序列化。该类定义如下:

public class Person {

  private String name;
  private Map<String, Person> children;

  // lots of other fields of different types with no issues
}
(许多字段(如子字段)是可选的,当为空时不会序列化)

到目前为止,我一直将子对象存储在
列表中,没有任何问题,但许多新用例需要访问名称集或使用其名称作为键的特定人员。这就是为什么我决定使用地图来存储它们

经过一些研究,我认为最好的方法是使用注释
@JsonSerialize
@JsonSerialize
,分别使用
JsonSerializer
JsonSerializer
作为字段子项的参数:

public class Person {

  private String id;

  @JsonSerialize(using=MySerializer.class)
  @JsonDeserialize(using=MyDeserializer.class)
  private Map<String, Person> friends;

  // lots of other fields
}
这很奇怪,因为我定义了一个默认构造函数。这是我的自定义反序列化程序:

public class MyDeserializer extends JsonDeserializer<Map<String, Person>> {

    public MyDeserializer() {
    }

    @Override
    public Map<String, Person> deserialize(JsonParser jp, DeserializationContext ctxt)
      throws IOException, JsonProcessingException {
      JsonNode personsNodeArray = jp.getCodec().readTree(jp);
      Map<String, Person> newChildren = null;
      if (personsNodeArray.isArray() && personsNodeArray.size() > 0) {
        newChildren = new HashMap<String, Person>();
        for (JsonNode personNode : personsNodeArray) {
          String id = personNode.get("name").asText();
          // jsonMapper is a default ObjectMapper
          newChildren.put(id, jsonMapper.readValue(personNode.toString(), Person.class));
        }
      }
      return newChildren;
    }
  }
公共类MyDeserializer扩展JsonDeserializer{
公共MyDeserializer(){
}
@凌驾
公共映射反序列化(JsonParser jp,反序列化上下文ctxt)
抛出IOException、JsonProcessingException{
JsonNode personnoderray=jp.getCodec().readTree(jp);
Map newChildren=null;
if(personsNodeArray.isArray()&&personsNodeArray.size()>0){
newChildren=newhashmap();
for(JsonNode personNode:PersonNodeArray){
String id=personNode.get(“name”).asText();
//jsonMapper是默认的对象映射器
newChildren.put(id,jsonMapper.readValue(personNode.toString(),Person.class));
}
}
归还新生子女;
}
}

你也可以考虑把儿童信息作为一组人,然后转换成一个地图。您可以定义setter方法(或构造函数参数)来接受

列表
,然后将每个元素放入
映射子项
字段。这将避免定制序列化不必要的复杂性

以下是一个例子:

public class JacksonChildren {
    public static final String JSON = "{\"name\":\"Bob\", \"children\":[{\"name\":\"Jimmmy\"}," +
            "{\"name\":\"Judy\"}]}";

    public static class Person {
        public String name;
        private Map<String, Person> children = new HashMap<>();

        public void setChildren(final List<Person> children) {
            for (Person p : children) {
                this.children.put(p.name, p);
            }
        }

        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", children=" + children +
                    '}';
        }
    }

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

}
public class MyDeserializer extends JsonDeserializer<Map<String, Person>> {

    public MyDeserializer() {
    }

    @Override
    public Map<String, Person> deserialize(JsonParser jp, DeserializationContext ctxt)
      throws IOException, JsonProcessingException {
      JsonNode personsNodeArray = jp.getCodec().readTree(jp);
      Map<String, Person> newChildren = null;
      if (personsNodeArray.isArray() && personsNodeArray.size() > 0) {
        newChildren = new HashMap<String, Person>();
        for (JsonNode personNode : personsNodeArray) {
          String id = personNode.get("name").asText();
          // jsonMapper is a default ObjectMapper
          newChildren.put(id, jsonMapper.readValue(personNode.toString(), Person.class));
        }
      }
      return newChildren;
    }
  }
public class JacksonChildren {
    public static final String JSON = "{\"name\":\"Bob\", \"children\":[{\"name\":\"Jimmmy\"}," +
            "{\"name\":\"Judy\"}]}";

    public static class Person {
        public String name;
        private Map<String, Person> children = new HashMap<>();

        public void setChildren(final List<Person> children) {
            for (Person p : children) {
                this.children.put(p.name, p);
            }
        }

        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", children=" + children +
                    '}';
        }
    }

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

}
Person{name='Bob', children={Judy=Person{name='Judy', children={}}, Jimmmy=Person{name='Jimmmy', children={}}}}