尽管序列化工作正常,但是在反序列化另一个值为另一个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。