【问题标题】:How to do custom serialization/deserialization using JACKSON?如何使用 JACKSON 进行自定义序列化/反序列化?
【发布时间】:2012-10-18 01:47:26
【问题描述】:

我正在尝试将以下 gson 序列化转换为 JACKSON 序列化。请让我知道我需要更改哪些内容才能使其适用于 JACKSON

public class AbstractElementAdapter 
    implements JsonSerializer<AbstractElement>, JsonDeserializer<AbstractElement>
{
    @Override
    public JsonElement serialize(AbstractElement src, Type typeOfSrc, JsonSerializationContext context) {
        JsonObject result = new JsonObject();
        JsonObject properties = context.serialize(src, src.getClass()).getAsJsonObject();

        if (src instanceof TruncatedElement) {
            result.add("type", new JsonPrimitive(((TruncatedElement) src).getClassName()));
            properties.remove("className");
        } else {
            result.add("type", new JsonPrimitive(src.getClass().getSimpleName()));
        }

        result.add("properties", properties);

        return result;
    }

    @Override
    public AbstractElement deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject jsonObject = json.getAsJsonObject();
        String type = jsonObject.get("type").getAsString();
        JsonElement element = jsonObject.get("properties");

        try {
            return context.deserialize(element, Class.forName("com.zreflect.emyed.whiteboard.model.element." + type));
        } catch (ClassNotFoundException cnfe) {
            throw new JsonParseException("Unknown element type: " + type, cnfe);
        }
    }
}

【问题讨论】:

    标签: java jackson gson


    【解决方案1】:

    您可以创建一个自定义序列化程序,如下所示:

      public class ItemSerializer extends JsonSerializer<AbstractElement> {
            @Override
            public void serialize(AbstractElement src, JsonGenerator jgen, SerializerProvider provider)
                    throws IOException, JsonProcessingException {
                jgen.writeStartObject();
    
                if (src instanceof TruncatedElement) {
                    jgen.writeStringField("type",((TruncatedElement) src).getClassName());
                    jgen.writeObjectFieldStart("properties");
                    //use  jgen.writeStringField();  
                    //jgen.writeNumberField(); 
                    //etc to every one of the values, 
                    //but skipping className
                     jgen.writeEndObject();
    
    
                } else {
                    jgen.writeStringField("type", src.getClass().getSimpleName() );
                    //write everythin
                    jgen.writeObjectField("properties", src);
                }
    
                jgen.writeEndObject();
            }
        }
    

    并将其注册到 ObjectMapper 中,然后进行序列化:

    ObjectMapper mapper = new ObjectMapper();
    
    SimpleModule module = new SimpleModule();
    module.addSerializer(yourObject.class, new ItemSerializer());
    mapper.registerModule(module);
    
    String serialized = mapper.writeValueAsString(yourObject);
    

    为了跳过className,您还可以使用自定义字段过滤器,这里有一个很好的示例: http://www.baeldung.com/jackson-ignore-properties-on-serialization

    【讨论】:

    • 你从哪里得到 AbstractDocument.AbstractElement?我们只有 AbstractElement 类。
    • 如果只使用AbstractElement,它会进入无限循环
    • 对不起,这只是 AbstractAlement,自动导入添加了另一个
    【解决方案2】:

    Jackson 允许您通过注解指定序列化程序。例如,请参见下面的简单示例:

    @JsonSerialize(using FooToStringSerializer)
    public class Foo implements Serializable {
    
        private String bar;
    
        public Foo(String bar) {
            this.bar = bar;
    }
    

    然后,如果我只想看到对象被序列化的时间是bar,我会像这样创建序列化器:

    public class FooToStringSerializer extends JsonSerializer<Foo> {
    
        @Override
        public void serialize(final Foo value, final JsonGenerator jgen,
            final SerializerProvider provider) throws IOException
        {
            jgen.writeObject(value.getBar());
        }
    

    对于反序列化,您可以创建一个反序列化程序并将其注册到将进行反序列化的ObjectMapper

    要使用对象映射器注册反序列化器,请执行以下操作:

    ObjectMapper mapper = new ObjectMapper();
    SimpleModule module = new SimpleModule();
    module.addDeserializer(Item.class, new FooDeserializer());
    mapper.registerModule(module);
    

    有关自定义反序列化的一个非常容易理解的示例,请参阅此链接: http://www.baeldung.com/jackson-deserialization

    【讨论】:

      猜你喜欢
      • 2014-08-02
      • 2019-08-10
      • 2021-12-13
      • 2016-03-14
      • 2013-10-10
      • 2017-03-02
      • 1970-01-01
      • 2018-07-15
      • 2020-12-08
      相关资源
      最近更新 更多