英文:
Deserialize json with duplicate keys using Jackson
问题
Sure, here's the translation of the content you provided:
我正在尝试使用Jackson解析一个带有重复键的JSON数据,将其转换为Map<String, List<String>>
类型。
考虑以下数据:
{
"foo" : "val1",
"foo" : "val2",
"bar" : "val3"
}
我希望将其转换为Map<String, List<String>>
类型,示例如下:
+--------------+----------------------+
| 键 (String) | 值 (List<String>) |
+--------------+----------------------+
| foo | [val1, val2] |
| bar | [val3] |
+--------------+----------------------+
在使用Jackson处理这种情况时,最好的方法是什么?我希望在Jackson中有一种方法,可以为Map<String, List<String>>
类型注册自定义的反序列化逻辑。(请注意,我无法控制请求中发送的JSON数据)
非常感谢您的帮助。
英文:
I am trying to parse a json payload with duplicate keys to a Map<String, List<String>>
using Jackson
Consider the following payload
{
"foo" : "val1",
"foo" : "val2",
"bar" : "val3"
}
I want to convert this to a Map<String, List<String>>
type.
ex:
+--------------+----------------------+
| Key (String) | Value (List<String>) |
+--------------+----------------------+
| foo | [val1, val2] |
| bar | [val3] |
+--------------+----------------------+
What would be the best way to handle this with Jackson? I'm hoping that there's a way in Jackson where I can register a custom deserialization logic for Map<String, List<String>>
type. (Note that I have no control over the json payload sent in the request)
Appreciate any help on this.
Thanks!
答案1
得分: 1
检查它是否适用于您。
使用 @JsonAnySetter
来反序列化未映射的 JSON 属性。@JsonAnySetter
注解可用于定义“任何设置器”变异器。
使用 @JsonAnyGetter
注解来序列化任何任意属性。@JsonAnyGetter
可用于返回 Map 的方法上。
POJO 定义
Test.java
package oct2020.json;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
public class Test {
private Map<String, List<String>> keyValuesMap = new HashMap<String, List<String>>();
/**
* @return the keyValuesMap
*/
@JsonAnyGetter
public Map<String, List<String>> getKeyValuesMap() {
return keyValuesMap;
}
/**
* @param keyValuesMap the keyValuesMap to set
*/
public void setKeyValuesMap(Map<String, List<String>> keyValuesMap) {
this.keyValuesMap = keyValuesMap;
}
@JsonAnySetter
public void duplicateKeyValues(String key, String value) {
List<String> values = null;
if (!keyValuesMap.containsKey(key)) {
values = new ArrayList<String>();
} else {
values = keyValuesMap.get(key);
}
values.add(value);
keyValuesMap.put(key, values);
}
}
将 JSON 转换为所需格式。
JSONConverter.java
package oct2020.json;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JSONConverter {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
String json = "{\"foo\" : \"val1\",\"foo\" : \"val2\",\"bar\" : \"val3\","
+ "\"bar\" : \"val3\",\"bar\" : \"val3\",\"bar\" : \"val3\","
+ "\"bar\" : \"val3\",\"bar\" : \"val3\",\"bar\" : \"val3\","
+ "\"bar\" : \"val3\",\"bar\" : \"val3\"}";
Test test = mapper.readValue(json, Test.class);
Map<String, List<String>> keyValuesMap = test.getKeyValuesMap();
System.out.println(mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(keyValuesMap));
}
}
输出:
{
"bar" : [ "val3", "val3", "val3", "val3", "val3", "val3", "val3", "val3", "val3", "val3" ],
"foo" : [ "val1", "val2" ]
}
英文:
Check if it works for you.
Using @JsonAnySetter
to deserialize unmapped JSON properties. @JsonAnySetter
annotation can be used to define "any setter" mutator.
Using @JsonAnyGetter
Annotation to serialize any arbitrary properties. @JsonAnyGetter
can be used on a method which returns a Map.
POJO Definition
Test.java
package oct2020.json;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
public class Test {
private Map<String, List<String>> keyValuesMap = new HashMap<String, List<String>>();
/**
* @return the keyValuesMap
*/
@JsonAnyGetter
public Map<String, List<String>> getKeyValuesMap() {
return keyValuesMap;
}
/**
* @param keyValuesMap
* the keyValuesMap to set
*/
public void setKeyValuesMap(Map<String, List<String>> keyValuesMap) {
this.keyValuesMap = keyValuesMap;
}
@JsonAnySetter
public void duplicateKeyValues(String key, String value) {
List<String> values = null;
if (!keyValuesMap.containsKey(key)) {
values = new ArrayList<String>();
} else {
values = keyValuesMap.get(key);
}
values.add(value);
keyValuesMap.put(key, values);
}
}
Converting the json to desired format.
JSONConverter .java
package oct2020.json;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JSONConverter {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
String json = "{\n\"foo\" : \"val1\",\n\"foo\" : \"val2\",\n\"bar\" : \"val3\"\n,"
+ "\n\"bar\" : \"val3\"\n,\n\"bar\" : \"val3\"\n,\n\"bar\" : \"val3\"\n,"
+ "\n\"bar\" : \"val3\"\n,\n\"bar\" : \"val3\"\n,\n\"bar\" : \"val3\"\n,"
+ "\n\"bar\" : \"val3\"\n,\n\"bar\" : \"val3\"\n,\n\"bar\" : \"val3\"}";
Test test = mapper.readValue(json, Test.class);
Map<String, List<String>> keyValuesMap = test.getKeyValuesMap();
System.out.println(mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(keyValuesMap));
}
}
Output:
{
"bar" : [ "val3", "val3", "val3", "val3", "val3", "val3", "val3", "val3", "val3", "val3" ],
"foo" : [ "val1", "val2" ]
}
答案2
得分: 0
请将此属性JsonTypeInfo.As.EXISTING_PROPERTY
放入@JsonTypeInfo
注释中。可能会起作用。
英文:
please put this property JsonTypeInfo.As.EXISTING_PROPERTY in the @JsonTypeInfo annotation. It might work.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论