Jackson中的自定义Json反序列化器仅适用于Hashmap

时间:2016-05-09 09:35:17

标签: java json serialization jackson

我正在编写json序列化(使用Jackson)用于Java类的层次结构,即类由其他类组成。因为我没有序列化所有属性,所以我使用了JsonViews并且仅注释了我想要序列化的那些属性。此层次结构顶部的类包含一个Map,该Map也需要序列化/反序列化。是否可以仅为Map编写序列化器/解串器?我希望默认的序列化程序负责序列化其余的对象

为什么要这个?如果我为最顶层的类定义一个序列化器,那么我需要对所有对象进行序列化。 JsonGenerator对象似乎忽略了JsonView注释并序列化了所有属性。

1 个答案:

答案 0 :(得分:1)

当然可能。使用Map类泛型类型定义自定义Serializer,然后使用Jackson模块子系统绑定它。

这是一个例子:(它产生愚蠢的自定义序列化,但主体是有效的)

public class Test
{
    // the "topmost" class
    public static class DTO {
        public String name = "name";
        public boolean b = false; 
        public int i = 100;

        @JsonView(MyView.class)
        public Map<String, String> map; {
            map = new HashMap<>();
            map.put("key1", "value1");
            map.put("key2", "value2");
            map.put("key3", "value3");
        }
    }

    // just to prove it works with views...
    public static class MyView {}

    // custom serializer for Map 
    public static class MapSerializer extends JsonSerializer<Map> {
        @Override
        public void serialize(Map map, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
            // your custom serialization goes here ....
            gen.writeStartObject();
            gen.writeFieldName("map-keys");
            gen.writeStartArray();
            gen.writeString(map.keySet().toString());
            gen.writeEndArray();
            gen.writeFieldName("map-valuess");
            gen.writeStartArray();
            gen.writeString(map.values().toString());
            gen.writeEndArray();
            gen.writeEndObject();
        }
    }

    public static void main(String[] args) {
        SimpleModule module = new SimpleModule();
        module.addSerializer(Map.class, new MapSerializer());
        ObjectMapper mapper = new ObjectMapper();
        mapper.disable(MapperFeature.DEFAULT_VIEW_INCLUSION);
        mapper.registerModule(module);
        try {
            mapper.writerWithView(MyView.class).writeValue(System.out, new DTO());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}