为什么反序列化嵌套地图不起作用

时间:2019-05-17 05:56:37

标签: java json jackson

尽管序列化工作正常,但是在反序列化另一个值为另一个Map的Map时会引起问题。

我在类“ Holder”中有一个变量“ map”,其中包含“ ArrayHolder” POJO作为键,而值又是另一个以“ ArrayHolder”作为键的映射。

我尝试使用@JsonSerialize和@JsonDeserialize批注使用'keyUsing'对ArrayHolder键进行序列化和反序列化。

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。

0 个答案:

没有答案