将 JSON 个对象的数组映射到 java.util.Map,反之亦然
Map an array of JSON objects to a java.util.Map and vice versa
问题是如何将 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 字符串
您可以使用 Jackson 反序列化 JSON 字符串:
例如,如果您有 class Foo
public class Foo {
private Bar[] items;
// Constructor / Getters & Setters
}
而 class 有一个数组 class 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
class:
@JsonDeserialize(using = CustomDeserializer.class)
您的 Storage
class 看起来像;
@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>
之后构建你的 Map<Integer, Item>
。
希望这对您有所帮助。
您可以创建自己的自定义 Serializers/Deserializers 来实现此目的。 Jackson 提供了一种巧妙的方法来做到这一点。只需使用 @JsonDeserialize(using = YourDeserializer.class) 注释 Storage class 并具有在 YourDeserializer.
中转换 json 的逻辑
JSON 个对象数组是一个 Items 数组,对吧?那么,为什么不简单地将数组反序列化为 Java 项数组,然后从那里构建地图呢?
问题是如何将 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 字符串
您可以使用 Jackson 反序列化 JSON 字符串:
例如,如果您有 class Foo
public class Foo {
private Bar[] items;
// Constructor / Getters & Setters
}
而 class 有一个数组 class 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
class:
@JsonDeserialize(using = CustomDeserializer.class)
您的 Storage
class 看起来像;
@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>
之后构建你的 Map<Integer, Item>
。
希望这对您有所帮助。
您可以创建自己的自定义 Serializers/Deserializers 来实现此目的。 Jackson 提供了一种巧妙的方法来做到这一点。只需使用 @JsonDeserialize(using = YourDeserializer.class) 注释 Storage class 并具有在 YourDeserializer.
中转换 json 的逻辑JSON 个对象数组是一个 Items 数组,对吧?那么,为什么不简单地将数组反序列化为 Java 项数组,然后从那里构建地图呢?