从JSON反序列化复杂的地图结构

时间:2018-06-28 17:34:33

标签: java json jackson

我有这样的JSON结构:

Master Controller

我正在尝试将Jackson的结构转换成<!DOCTYPE html> <html> <head> <title>App</title> </head> <body> <form id="sendNameForm"> <input id="name" type="text" value="John"/> <button id="sendNameBtn" type="submit" disabled>Change</button> </form> <script src="jquery-1.12.4.js"></script> <script> $('#sendNameForm').submit(function() { var name = $('#name').val(); dis_enableNameSend(); alert("Success!"); return false; }); var name= $('#name').val(); function dis_enableNameSend(){ var newName = $('#name').val(); if(newName==name){ document.getElementById("sendNameBtn").disabled = true; }else{ document.getElementById("sendNameBtn").disabled = false; } } $('#name').on('input', function() { dis_enableNameSend(); }); </script> </body> </html> ,其中[ { "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<CustomObject, List<CustomObject>>,值是topLevelOneKey

所以我尝试了这个:

topLevelTwo

但是我收到此错误消息: List<CustomObject>]

有人可以指出我在做什么错吗?也许是一个代码示例,该如何实现?

2 个答案:

答案 0 :(得分:0)

json无效,因为您在结构中的同一级别混合了类型。我认为您可以通过“地图地图”实现所需的功能。我不确定您的自定义对象,因此我将使用字符串以防万一。

如果您这样定义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>>>(){});

答案 1 :(得分: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));

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