Java 用于地图序列化的Jackson模块

Java 用于地图序列化的Jackson模块,java,serialization,map,jackson,jackson-modules,Java,Serialization,Map,Jackson,Jackson Modules,我有一个类,它包含一个映射(带有非字符串键)和一些其他字段 public class MyClass() { private Map<KeyObject, OtherObject> map; private String someField; public MyClass(Map<KeyObject, OtherObject> map, String someField) { this.map = map; thi

我有一个类,它包含一个映射(带有非字符串键)和一些其他字段

public class MyClass() {
    private Map<KeyObject, OtherObject> map;
    private String someField;

    public MyClass(Map<KeyObject, OtherObject> map, String someField) {
        this.map = map;
        this.someField = someField;
    }

    // Getters & Setters
}
但这显然是错误的,因为我得到了一个例外:

keySerializer does not define valid handledType() -- must either register with method that takes type argument  or make serializer extend 'org.codehaus.jackson.map.ser.std.SerializerBase'
我可以将我的序列化程序和反序列化程序输入到MyClass,但是我必须手动解析所有这些,这是不合理的

更新:

通过使用注释,我成功地绕过了代码中的模块创建

@JsonDeserialize(using = keyDeserializer.class)
@JsonSerialize(using = keySerializer.class)
private Map<KeyObject, OtherObject> map;
然后手动反序列化我的密钥,但再次从我的密钥类的toString()输出


这不是最优的(此依赖于toString()方法)。有更好的方法吗?

最终使用了此序列化程序:

public class MapKeySerializer extends SerializerBase<Object> {
    private static final SerializerBase<Object> DEFAULT = new StdKeySerializer();
    private static final ObjectMapper mapper = new ObjectMapper();

    protected MapKeySerializer() {
    super(Object.class);
    }

    @Override
    public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException {
    return DEFAULT.getSchema(provider, typeHint);
    }

    @Override
    public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
    if (null == value) {
        throw new JsonGenerationException("Could not serialize object to json, input object to serialize is null");
    }
    StringWriter writer = new StringWriter();
    mapper.writeValue(writer, value);
    jgen.writeFieldName(writer.toString());
    }
}
public class MapKeyDeserializer extends KeyDeserializer {

    private static final ObjectMapper mapper = new ObjectMapper();

    @Override
    public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    return mapper.readValue(key, MyObject.class);
    }
}
注释我的地图:

@JsonDeserialize(keyUsing = MapKeyDeserializer.class)
@JsonSerialize(keyUsing = MapKeySerializer.class)
private Map<KeyObject, OtherObject> map;
@JsonDeserialize(keyUsing=MapKeyDeserializer.class)
@JsonSerialize(keyUsing=MapKeySerializer.class)
私人地图;

这是对我有效的解决方案,希望这对其他人有所帮助。

查看此问题和此。您的
KeyObject
对象的外观如何?请注意,您看到的是一个过时的Jackson版本。@chrylis目前我正在使用Jackson 1.9。使用jackson 2.x有没有一种简单的方法?你能分享一个链接吗?看起来很有帮助,但你可能想解释什么是AlgFilterKey,或者删除它,然后在它的位置放一些通用的东西。谢谢,这很有帮助
public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException {...}
public class MapKeySerializer extends SerializerBase<Object> {
    private static final SerializerBase<Object> DEFAULT = new StdKeySerializer();
    private static final ObjectMapper mapper = new ObjectMapper();

    protected MapKeySerializer() {
    super(Object.class);
    }

    @Override
    public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException {
    return DEFAULT.getSchema(provider, typeHint);
    }

    @Override
    public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
    if (null == value) {
        throw new JsonGenerationException("Could not serialize object to json, input object to serialize is null");
    }
    StringWriter writer = new StringWriter();
    mapper.writeValue(writer, value);
    jgen.writeFieldName(writer.toString());
    }
}
public class MapKeyDeserializer extends KeyDeserializer {

    private static final ObjectMapper mapper = new ObjectMapper();

    @Override
    public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    return mapper.readValue(key, MyObject.class);
    }
}
@JsonDeserialize(keyUsing = MapKeyDeserializer.class)
@JsonSerialize(keyUsing = MapKeySerializer.class)
private Map<KeyObject, OtherObject> map;