java - 将 JSON 对象数组映射到 java.util.Map,反之亦然

标签 java json fasterxml

问题是如何将 JSON 对象数组映射到 java.util.Map,其中每个键都是对象的某个指定属性,值是对象本身。

JSON:

{"items": [{"field1": 1, "field2": "Hello"}, {"field1": 2, "field2":"World"}]}

Java POJO:

public class Storage {
    private Map<Integer, Item> items;
}

public class Item {
    private Integer field1;
    private String field2;
}

那么有什么方法可以指定 ObjectMapper 在将项目数组反序列化到 Map 时,它应该使用每个 JSON 对象的 field1 属性作为键

最佳答案

如何反序列化JSON字符串

您可以使用 Jackson 反序列化 JSON 字符串:

例如,如果你有类 Foo

public class Foo {

   private Bar[] items;

   // Constructor / Getters & Setters

} 

那个类有一个类数组 Bar

 public class Bar {

     private int field1;
     private String field2;


     // Constructor / Getters & Setters

 }

如果字段名称与您的 JSON 字符串中的字段名称匹配,那么您可以执行以下操作来转换它:

String jsonString = "{\"items\": [{\"field1\": 1, \"field2\": \"Hello\"}, {\"field1\": 2, \"field2\":\"World\"}]}";

ObjectMapper mapper = new ObjectMapper();

Foo foo = mapper.readValue(jsonString, Foo.class);

如果您使用的是 Maven,则您的 pom.xml 中需要以下依赖项:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson.version}</version>
    </dependency>

解决问题的方法:

Option 1 - Custom Deserializer

写一个自定义JsonDeserializer将您的 JSON 字符串反序列化为 Storage带字段的对象 items类型 Map<String,Item>

 public class CustomDeserializer extends JsonDeserializer<Storage> {

    @Override
    public Storage deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
            throws IOException {

        Map<Integer, Item> map = new HashMap<>();

        ObjectCodec oc = jsonParser.getCodec();
        JsonNode rootNode = oc.readTree(jsonParser);
        JsonNode items = rootNode.get("items");

        for (int i = 0; i < items.size(); i++) {

            JsonNode childNode = items.get(i);

            Item item = new Item(childNode.get("field1").asInt(), childNode.get("field2").asText());

            map.put(item.getField1(), item);
        }

        return new Storage(map);
    }
}

然后您将注释您的 Storage类如下:

@JsonDeserialize(using = CustomDeserializer.class)

你的 Storage类看起来像;

@JsonDeserialize(using = CustomDeserializer.class)
public class Storage {

   private Map<Integer, Item> items;

   public Storage(Map<Integer, Item> map) {
    this.items = map;
   }

   ...

}

Option 2 - Create Map post deserialization

将 JSON 字符串反序列化为 Storage具有 Item 数组的对象如开头所述,然后构建您的 Map<Integer, Item>之后。

希望这对您有所帮助。

关于java - 将 JSON 对象数组映射到 java.util.Map,反之亦然,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33914460/

相关文章:

javascript - XML 到 JavaScript 对象

java - 是否必须在 Gson 处理的类上保留默认构造函数?

java - 使用用索引项表示的集合生成 JSON

java - 男性和女性字符串的正则表达式是什么

javascript - 谷歌浏览器扩展内容安全政策

java - FasterXML jackson-dataformat-xml 序列化版本和编码未添加到 xml

java - 如何使用 `com.fasterxml.jackson.core.JsonParser` 确定 json 数组的大小

java - Jaunt Java getText() 返回正确的文本,但有很多 "?"

java - 用于添加到二维数组的 while 和 for 循环

Java:读取、编辑和创建文本文件