从JSON反序列化复杂的映射结构

3
我有一个像这样的JSON结构:
[
    {
        "topLevelOne": {
            "property1": false,

        },
        "topLevelTwo": [
            {
                "property2": false,
                "property3": false,
                "property4": false,
            },
            {
                "property2": false,
                "property3": false,
                "property4": false,
            }
        ]
    },

    {
        "topLevelOne": {
            "property1": false,

        },
        "topLevelTwo": [
            {
                "property2": false,
                "property3": false,

            },
            {
                "property2": false,
                "property3": false,
            },
        ]
    }
]

我正在尝试使用Jackson将此结构转换为Map<CustomObject,List<CustomObject>>,其中topLevelOne对应于Key,值为topLevelTwoList<CustomObject>)。
所以我尝试了这个:
ObjectMapper JSONMapper = new ObjectMapper();
Map<CustomObject, List<CustomObject>> map = JSONMapper.readValue(json, new TypeReference<Map<CustomObject, List<CustomObject>>>(){});

然而我收到了以下错误信息: com.fasterxml.jackson.databind.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class CustomObject]

请问有谁能指出我在这里做错了什么?或者提供一个代码示例来解决这个问题?

你能展示一下CustomObject类吗?它有公共的无参构造函数和每个字段的setter方法吗?或者字段是final类型的,你想使用构造函数吗? - GotoFinal
2个回答

0

JSON不是有效的,因为您在结构的同一级别上混合了类型。我认为您可以通过Map of Maps实现所需的功能。由于我不确定您的自定义对象,因此我将使用字符串以防有所帮助。

如果您像这样定义JSON:

[{
        "topLevelOne": [{
            "property1": false
        }],
        "topLevelTwo": [{
                "property2": false,
                "property3": false,
                "property4": false
            },
            {
                "property2": false,
                "property3": false,
                "property4": false
            }
        ]
    },

    {
        "topLevelOne": [{
            "property1": false

        }],
        "topLevelTwo": [{
                "property2": false,
                "property3": false

            },
            {
                "property2": false,
                "property3": false
            }
        ]
    }
]

你可以用类似这样的方式来阅读它:

Map<String, Map<String,String>> map = mapper.readValue(json, new TypeReference <Map<String, Map<String,String>>>(){});

0

内置的Jackson Map反序列化器使用字段名称作为键,并将其映射到相关字段值。

您的JSON结构不同-它是一个条目列表。反序列化您的地图的最简单方法是读取列表,然后在之后构建地图。

您需要一个辅助对象来模拟这些条目:

class CustomEntry {
    private CustomKey topLevelOne;
    private List<CustomObject> topLevelTwo;

    @JsonCreator
    public CustomEntry(@JsonProperty("topLevelOne") CustomKey topLevelOne, @JsonProperty("topLevelTwo") List<CustomObject> topLevelTwo) {
        this.topLevelOne = topLevelOne;
        this.topLevelTwo = topLevelTwo;
    }

    public CustomKey getTopLevelOne() {
        return topLevelOne;
    }

    public List<CustomObject> getTopLevelTwo() {
        return topLevelTwo;
    }
}

然后,

String json = ...
ObjectMapper mapper = new ObjectMapper();
// Read the list of map entries
List<CustomEntry> entries = mapper.readValue(json, new TypeReference<List<CustomEntry>>(){});
// Build the map
Map<CustomKey, List<CustomObject>> map = entries.stream().collect(Collectors.toMap(e -> e.topLevelOne, e -> e.topLevelTwo));

你可以创建一个自定义反序列化器直接从列表中读取地图,但我不确定这是否值得额外的努力。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接