Почему не работает десериализация вложенной карты - PullRequest
0 голосов
/ 17 мая 2019

Хотя сериализация работает нормально, при десериализации карты, значение которой является другой картой, возникает проблема.

У меня есть переменная 'map' в классе 'Holder', которая содержит POJO ArrayHolder в качестве ключа и значение в качестве другой карты с ArrayHolder в качестве ключа.

Я попытался сериализовать и десериализовать ключи ArrayHolder с помощью аннотаций @JsonSerialize и @JsonDeserialize с помощью keyUsing.

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.KeyDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

public class Sample {
    public static void main(String[] a) throws Exception
    {
        ObjectMapper om = new ObjectMapper();

        Map<ArrayHolder, Map<ArrayHolder, Object[]>> outerMap = new HashMap<>();
        Map<ArrayHolder, Object[]> innerMap = new HashMap<>();
        Holder holder = new Holder();
        holder.setStr("hello world");
        Object[] array = new Object[]{"siva", 1000, 1.1};
        ArrayHolder arrHolder = new ArrayHolder();
        arrHolder.setArr(array);
        innerMap.put(arrHolder, array);
        outerMap.put(arrHolder, innerMap);
        holder.setMap(outerMap);

        String serializedHolder = om.writeValueAsString(holder);
        System.out.println("serialized : " + serializedHolder);

        Holder deserializedHolder = om.readValue(serializedHolder, Holder.class);
        System.out.println("deserialized : " + deserializedHolder);
    }
}

class Holder
{
    @JsonSerialize(keyUsing = ArrayKeySerializer.class)
    @JsonDeserialize(keyUsing = ArrayKeyDeserializer.class)
    private Map<ArrayHolder, Map<ArrayHolder, Object[]>> map;
    private String str;

    public String getStr() {
        return str;
    }
    public void setStr(String str) {
        this.str = str;
    }
    public Map<ArrayHolder, Map<ArrayHolder, Object[]>> getMap() {
        return map;
    }
    public void setMap(Map<ArrayHolder, Map<ArrayHolder, Object[]>> map) {
        this.map = map;
    }
}

class ArrayHolder 
{
    private Object[] arr;

    public Object[] getArr()
    {
        return arr;
    }

    public void setArr(Object[] arr) {
        this.arr = arr;
    }
}

class ArrayKeySerializer extends JsonSerializer<ArrayHolder> {

    private static final ObjectMapper mapper = new ObjectMapper();

    @Override
    public void serialize(ArrayHolder value, JsonGenerator gen, SerializerProvider serializers) throws IOException 
    {
        if(value != null)
        {
            gen.writeFieldName(mapper.writeValueAsString(Arrays.asList(value.getArr())));
        }
    }
}

class ArrayKeyDeserializer extends KeyDeserializer
{
    private static final ObjectMapper mapper = new ObjectMapper();

    @Override
    public Object deserializeKey(String key, DeserializationContext context) throws IOException, JsonProcessingException 
    {
        ArrayHolder arrayHolder = new ArrayHolder();
        arrayHolder.setArr(mapper.readValue(key, Object[].class));
        return arrayHolder;
    }
}

вывод:

serialized : {"map":{"[\"siva\",1000,1.1]":{"[\"siva\",1000,1.1]":["siva",1000,1.1]}},"str":"hello world"}

Exception in thread "main" java.lang.IllegalArgumentException: Can not find a (Map) Key deserializer for type [simple type, class smart.ArrayHolder]
 at [Source: N/A; line: -1, column: -1]
    at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3530)
    at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:3449)
    at Sample.main(Sample.java:39)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class smart.ArrayHolder]
 at [Source: N/A; line: -1, column: -1]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:284)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._handleUnknownKeyDeserializer(DeserializerCache.java:587)
    at com.fasterxml.jackson.databind.deser.DeserializerCache.findKeyDeserializer(DeserializerCache.java:168)
    at com.fasterxml.jackson.databind.DeserializationContext.findKeyDeserializer(DeserializationContext.java:500)
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer.createContextual(MapDeserializer.java:231)
    at com.fasterxml.jackson.databind.DeserializationContext.handleSecondaryContextualization(DeserializationContext.java:685)
    at com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(DeserializationContext.java:446)
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer.createContextual(MapDeserializer.java:245)
    at com.fasterxml.jackson.databind.DeserializationContext.handleSecondaryContextualization(DeserializationContext.java:685)
    at com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(DeserializationContext.java:446)
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer.findDeserializer(StdDeserializer.java:948)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:447)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:296)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
    at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
    at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:477)
    at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:3908)
    at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3523)
    ... 2 more

Я получил правильные сериализованные данные. Но десериализация вызывает эту проблему. Он говорит, что не может найти десериализатор ключа карты для ArrayHolder. Но я определил ArrayKeyDeserializer.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...