使用 Jackson 使用重复键反序列化 json

Deserialize json with duplicate keys using Jackson

我正在尝试使用 Jackson

将具有重复 键的 json 负载 解析为 Map<String, List<String>>

考虑以下负载

{
"foo" : "val1",
"foo" : "val2",
"bar" : "val3"
}

我想将其转换为 Map<String, List<String>> 类型。

例如:

+--------------+----------------------+
| Key (String) | Value (List<String>) |
+--------------+----------------------+
| foo          | [val1, val2]         |
| bar          | [val3]               |
+--------------+----------------------+

与 Jackson 一起处理这件事的最佳方式是什么?我希望 Jackson 有一种方法可以为 Map<String, List<String>> 类型注册自定义反序列化逻辑。 (请注意,我无法控制请求中发送的 json 负载)

感谢任何帮助。

谢谢!

请将此 属性 JsonTypeInfo.As.EXISTING_PROPERTY 放在 @JsonTypeInfo 注释中。可能有用。

检查它是否适合您。

使用 @JsonAnySetter 反序列化未映射的 JSON 属性。 @JsonAnySetter 注释可用于定义“任何 setter” 变元。

使用 @JsonAnyGetter 注释序列化任意属性。 @JsonAnyGetter 可用于 returns 地图的方法。

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 转换为所需格式。

JSON转换器 .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));
    }
}

输出:

{
  "bar" : [ "val3", "val3", "val3", "val3", "val3", "val3", "val3", "val3", "val3", "val3" ],
  "foo" : [ "val1", "val2" ]
}