当前位置: 首页 > 面试题库 >

用于地图序列化的Jackson模块

锺离浩慨
2023-03-14
问题内容

我有一个包含地图(带有非字符串键)和其他一些字段的类。

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
}

我想使用Jackson来对该类进行序列化和反序列化。我看到了另一种方法,因此决定尝试使用杰克逊模块。

我关注了这篇文章,并扩展了JsonDeserializer和JsonSerializer。问题在于这些类应该被键入,因此看起来应该像

public class keyDeserializer extends JsonDeserializer<Map<KeyObject, OtherObject>> {
...
}

KeySerializer也是如此。

然后添加到模块:

module.addSerializer(new keySerializer());
module.addDeserializer(Map.class, new keyDeserializer());

但这显然是错误的,因为我遇到了一个例外:

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()输出中对整个映射结构进行序列化/反序列化。因此尝试了不同的注释:

@JsonDeserialize(keyUsing = MyKeyDeserializer.class)
private Map<KeyObject, OtherObject> map;

MyKeyDeserializer在哪里扩展org.codehaus.jackson.map.KeyDeserializer并覆盖方法

public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException {...}

然后手动反序列化我的密钥,但再次从我的密钥类的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;

这是为我工作的解决方案,希望对您有所帮助。



 类似资料:
  • 我有一个具有两个属性的JSON对象:“key”(字符串)和“value”(可以反序列化为Java bean)。 问题是,给定一个这样的物体列表,我能把它反序列化为一张地图吗? 当前使用Jackson-databind 2.1

  • 序列化和反序列化的方式不同于 我已经创建了两个序列化程序 和 我用Jackson查看了序列化/反序列化映射 ,但找不到解决方案。

  • 我目前正在尝试使用Jackson2.8.4将自定义映射类型序列化和反序列化为JSON。我已经设法基于这个答案实现了序列化,但我正在与反序列化作斗争。下面是一个例子:

  • 我有一个Pojo对象,由Jersey使用jackson序列化: 序列化产生了一个像这样的Json: 但是,当我尝试像这样反序列化来自客户端的消息时: 我得到以下错误: 无法识别的字段“键”(类com.example.server.api.书摘),未标记为可忽略 我不知道问题是来自服务器生成的JSOn还是来自客户端的反序列化。 您知道问题是什么以及如何纠正吗? 非常谢谢。

  • 问题内容: 如何将作为地图的属性序列化为地图的值列表?我已经能够使用吸气剂上的注释进行其他简单的转换。但是,我不确定我想做什么。 问题答案: 我们需要类似的东西,在我们的案例中,我们使用了您所评论的自定义项,这很简单: 使用它的代码:

  • 嗨,我正面临着地图序列化的问题,其中关键是一个自定义类。