JSon-嵌套地图的自定义键序列化 [英] JSon - custom key serialization of nested maps
问题描述
我有一个嵌套的Map<StructureNode, Map<String, String>>
,为此我需要一个自定义键序列化器&反序列化器(StructureNode
包含对其他对象的引用,这些对象需要用作此映射的键).我为此使用了以下方法:
I have a nested Map<StructureNode, Map<String, String>>
for which I need a custom key serializer & deserializer (StructureNode
contains references to other objects which are needed to function as key for this map). I used the following method for this:
给出以下结果.自定义序列化器:
Giving the following result. Custom Serializer:
public class StructureNodeKeySerializer extends JsonSerializer<StructureNode> {
private static final ObjectMapper mapper = new ObjectMapper();
@Override
public void serialize(StructureNode value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
StringWriter writer = new StringWriter();
mapper.writeValue(writer, value.copyUpwards());
gen.writeFieldName(writer.toString());
}
}
自定义反序列化器:
public class StructureNodeKeyDeserializer extends KeyDeserializer {
private static final ObjectMapper mapper = new ObjectMapper();
@Override
public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException {
return mapper.readValue(key, StructureNode.class);
}
}
用法:
@JsonDeserialize(keyUsing = StructureNodeKeyDeserializer.class) @JsonSerialize(keyUsing = StructureNodeKeySerializer.class)
private Map<StructureNode, String> structureIds;
@JsonDeserialize(keyUsing = StructureNodeKeyDeserializer.class) @JsonSerialize(keyUsing = StructureNodeKeySerializer.class)
private Map<StructureNode, Map<String, String>> metadata;
这正确地序列化了Map<StructureNode, String>
,但是将其应用于嵌套的Map<StructureNode, Map<String, String>>
,则会出现以下错误:
This correctly serializes a Map<StructureNode, String>
, but applied to a nested Map<StructureNode, Map<String, String>>
, it gives the following error:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: java.lang.String cannot be cast to structure.StructureNode
杰克逊似乎对子图"使用了相同的自定义序列化方法.是否有一种解决此问题的好方法,而无需用另一个自定义对象(非Map
)替换子图"?
Jackson seems to be using the same custom serialization method for the "sub-map". Is there a good way to solve this problem, without replacing the "sub-map" with another custom (non-Map
) object?
推荐答案
您可以使用
public static class Bean{
@JsonSerialize(using = MapStructureNodeKeySerializer.class)
public Map<StructureNode, Map<String, String>> metadata;
}
与实现序列化器的方式略有不同:
And implement your serializer a little bit differently:
public static class MapStructureNodeKeySerializer
extends JsonSerializer<Map<StructureNode, Object>> {
private static final ObjectMapper mapper = new ObjectMapper();
@Override
public void serialize(Map<StructureNode, Object> value, JsonGenerator gen,
SerializerProvider serializers) throws IOException {
gen.writeStartObject();
for(Map.Entry<StructureNode, Object> val: value.entrySet()){
// your custom serialization code here
StringWriter writer = new StringWriter();
mapper.writeValue(writer, val.getKey().copyUpwards());
gen.writeObjectField(writer.toString(), val.getValue());
}
gen.writeEndObject();
}
}
或者如果您想保留keyUsing = StructureNodeKeySerializer.class
public static class Bean{
@JsonSerialize(keyUsing = StructureNodeKeySerializer.class)
public Map<StructureNode, Map<String, String>> metadata;
}
您可以像这样实现它:
public static class StructureNodeKeySerializer extends JsonSerializer {
private static final ObjectMapper mapper = new ObjectMapper();
@Override
public void serialize(Object value, JsonGenerator gen,
SerializerProvider serializers) throws IOException {
if (value instanceof StructureNode){ // <= type of 1-st level Map key
// your custom serialization code here
StringWriter writer = new StringWriter();
mapper.writeValue(writer, ((StructureNode)value).copyUpwards());
gen.writeFieldName(writer.toString());
}else if(value instanceof String){ // <= type of 2-nd level Map key
gen.writeFieldName((String) value);
}
}
}
这篇关于JSon-嵌套地图的自定义键序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!