Jackson JSON - Deserialize Commons MultiMap

旧时模样 提交于 2019-11-30 23:30:51

问题


i want to serialize and deserialize a MultiMap (Apache Commons 4) using JSON.

Piece of code to test:

MultiMap<String, String> map = new MultiValueMap<>();
map.put("Key 1", "Val 11");
map.put("Key 1", "Val 12");
map.put("Key 2", "Val 21");
map.put("Key 2", "Val 22");

ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(map);
MultiMap<String, String> deserializedMap = mapper.readValue(jsonString, MultiValueMap.class);

The serialization works fine and results in a format I would expect:

{"Key 1":["Val 11","Val 12"],"Key 2":["Val 21","Val 22"]}

Unfortunately the deserialization produces a result that is not the way it should look like: After the deserialization, the Multimap contains an ArrayList inside an ArrayList for the values of a key, not an single ArrayList for the key containing the values.

This result is produced due to the fact that the put() method of the multi map is called to add the array found in the json string, as the MultiMap implements the Map interface.

The MultiMap implementation itself again then creates an ArrayList if a new value is put to a non existing key.

Is there any way to circumvent this?

Thank you for your help!


回答1:


Being assured from Oxford dictionary that circumvent means to "find a way around (an obstacle)", here is a simple work around.

First I created a method that generate the same MultiValueMap as yours above. And I use the same approach to parse it as a json string.

I then created the following deserialization method

public static MultiMap<String,String> doDeserialization(String serializedString) throws JsonParseException, JsonMappingException, IOException {

    ObjectMapper mapper = new ObjectMapper();
    Class<MultiValueMap> classz = MultiValueMap.class;
    MultiMap map = mapper.readValue(serializedString, classz);
    return (MultiMap<String, String>) map;


}

Of course this alone falls in the exact issue you mentionned above, therefore I created the doDeserializationAndFormatmethod: it will iterate through each "list inside a list" correponding to a given key and associate one by one the values to the key

public static MultiMap<String, String> doDeserializationAndFormat(String serializedString) throws JsonParseException, JsonMappingException, IOException {
    MultiMap<String, String> source = doDeserialization(serializedString);
    MultiMap<String, String> result  =  new MultiValueMap<String,String>();
    for (String key: source.keySet()) {


        List allValues = (List)source.get(key);
        Iterator iter = allValues.iterator();

        while (iter.hasNext()) {
            List<String> datas = (List<String>)iter.next();

            for (String s: datas) {
                result.put(key, s);
            }
        }

    }

    return result;

}

Here is a simple call in a main method:

MultiValueMap<String,String> userParsedMap = (MultiValueMap)doDeserializationAndFormat(stackMapSerialized);
System.out.println("Key 1 = " + userParsedMap.get("Key 1") );
System.out.println("Key 2 = " + userParsedMap.get("Key 2") );

Hope this helps.



来源:https://stackoverflow.com/questions/29604319/jackson-json-deserialize-commons-multimap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!