The question is how to map an array of JSON objects to a java.util.Map
where each key would be some specified property of an object and the value is the object itself.
问题是如何将JSON对象数组映射到java.util。映射每个键将是一个对象的指定属性,而值是对象本身。
JSON:
JSON:
{"items": [{"field1": 1, "field2": "Hello"}, {"field1": 2, "field2":"World"}]}
Java POJO:
Java POJO:
public class Storage {
private Map<Integer, Item> items;
}
public class Item {
private Integer field1;
private String field2;
}
So is there a some way to specify to ObjectMapper
that it should use field1
property of each JSON object as key when deserializing array of items to the Map
?
那么,是否有一种方法可以指定ObjectMapper,它应该将每个JSON对象的field1属性作为键,将数组中的项反序列化到映射中?
3 个解决方案
#1
7
How to deserialize a JSON string
如何反序列化JSON字符串?
You can use Jackson to deserialize a JSON string:
您可以使用Jackson来反序列化JSON字符串:
For example if you have class Foo
例如,如果你有Foo类
public class Foo {
private Bar[] items;
// Constructor / Getters & Setters
}
And that class has an array of class Bar
这个类有一个类Bar的数组
public class Bar {
private int field1;
private String field2;
// Constructor / Getters & Setters
}
Where the field names match those in your JSON string then you can do the following to convert it:
如果字段名与JSON字符串中的字段名匹配,那么您可以执行以下操作来转换它:
String jsonString = "{\"items\": [{\"field1\": 1, \"field2\": \"Hello\"}, {\"field1\": 2, \"field2\":\"World\"}]}";
ObjectMapper mapper = new ObjectMapper();
Foo foo = mapper.readValue(jsonString, Foo.class);
If you are using Maven, the following dependency would be required in your pom.xml:
如果您正在使用Maven,则在您的pom.xml中需要以下依赖项:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
Approaches to solve your problem:
解决问题的方法:
Option 1 - Custom Deserializer
选项1 -自定义反序列化器
Write a custom JsonDeserializer
to deserialize your JSON string into a Storage
object with a field items
of type Map<String,Item>
编写一个自定义的JsonDeserializer,以便将JSON字符串反序列化为一个存储对象,其中包含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);
}
}
You would then annotate your Storage
class with the following:
然后,您将在存储类中注释如下:
@JsonDeserialize(using = CustomDeserializer.class)
Your Storage
class would look something like;
您的存储类看起来是这样的;
@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
选项2 -创建映射后反序列化
Deserialize the JSON string into a Storage
object with an array of Item
as described at the beginning and then construct your Map<Integer, Item>
after.
将JSON字符串反序列化为存储对象,并使用开头描述的项数组,然后构造映射
Hope this helps.
希望这个有帮助。
#2
1
You can create your own custom Serializers/Deserializers to achieve this. Jackson provides a neat way of doing this. Just annotate the Storage class with @JsonDeserialize(using = YourDeserializer.class) and have the logic to convert the json in YourDeserializer.
您可以创建自己的自定义序列化器/反序列化器来实现这一点。Jackson提供了一种简洁的方法。只需使用@JsonDeserialize(使用= yourdeserizer .class)注释存储类,并具有在YourDeserializer中转换json的逻辑。
#3
0
The array of JSON objects is an array of Items, right? So why not simply deserialize the array into a Java array of Items and then build the Map from there?
JSON对象的数组是项目的数组,对吧?那么,为什么不简单地将数组反序列化为项目的Java数组,然后从那里构建映射呢?
#1
7
How to deserialize a JSON string
如何反序列化JSON字符串?
You can use Jackson to deserialize a JSON string:
您可以使用Jackson来反序列化JSON字符串:
For example if you have class Foo
例如,如果你有Foo类
public class Foo {
private Bar[] items;
// Constructor / Getters & Setters
}
And that class has an array of class Bar
这个类有一个类Bar的数组
public class Bar {
private int field1;
private String field2;
// Constructor / Getters & Setters
}
Where the field names match those in your JSON string then you can do the following to convert it:
如果字段名与JSON字符串中的字段名匹配,那么您可以执行以下操作来转换它:
String jsonString = "{\"items\": [{\"field1\": 1, \"field2\": \"Hello\"}, {\"field1\": 2, \"field2\":\"World\"}]}";
ObjectMapper mapper = new ObjectMapper();
Foo foo = mapper.readValue(jsonString, Foo.class);
If you are using Maven, the following dependency would be required in your pom.xml:
如果您正在使用Maven,则在您的pom.xml中需要以下依赖项:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
Approaches to solve your problem:
解决问题的方法:
Option 1 - Custom Deserializer
选项1 -自定义反序列化器
Write a custom JsonDeserializer
to deserialize your JSON string into a Storage
object with a field items
of type Map<String,Item>
编写一个自定义的JsonDeserializer,以便将JSON字符串反序列化为一个存储对象,其中包含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);
}
}
You would then annotate your Storage
class with the following:
然后,您将在存储类中注释如下:
@JsonDeserialize(using = CustomDeserializer.class)
Your Storage
class would look something like;
您的存储类看起来是这样的;
@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
选项2 -创建映射后反序列化
Deserialize the JSON string into a Storage
object with an array of Item
as described at the beginning and then construct your Map<Integer, Item>
after.
将JSON字符串反序列化为存储对象,并使用开头描述的项数组,然后构造映射
Hope this helps.
希望这个有帮助。
#2
1
You can create your own custom Serializers/Deserializers to achieve this. Jackson provides a neat way of doing this. Just annotate the Storage class with @JsonDeserialize(using = YourDeserializer.class) and have the logic to convert the json in YourDeserializer.
您可以创建自己的自定义序列化器/反序列化器来实现这一点。Jackson提供了一种简洁的方法。只需使用@JsonDeserialize(使用= yourdeserizer .class)注释存储类,并具有在YourDeserializer中转换json的逻辑。
#3
0
The array of JSON objects is an array of Items, right? So why not simply deserialize the array into a Java array of Items and then build the Map from there?
JSON对象的数组是项目的数组,对吧?那么,为什么不简单地将数组反序列化为项目的Java数组,然后从那里构建映射呢?