序列化一个类与杰克逊两种不同的方式(Serialize one class in two diffe

2019-06-27 10:03发布

在我们的项目之一,我们使用Java web应用程序跟一个MongoDB实例。 在数据库中,我们使用DBRefs跟踪某个对象的关系。 我们(德),但以杰克逊(使用MongoDB的杰克逊映射器)POJO对象序列化。

但是,我们使用相同的POJO到随后的(de)序列化到外面的世界,在那里我们与呈现JSON前端交易。

现在,我们需要一种方法用于序列化对于外界包含从引用的对象DBRef (这样UI能呈现完整的对象),而我们显然希望有DBRef写入到数据库中,而不是整个宾语。

现在,我写了一些未经检验的静态嵌套类代码:

public static class FooReference {
    public DBRef<Foo> foo;

    // FIXME how to ensure that this doesn't go into the database?
    public Foo getFoo() {
        return foo.fetch();
    }
}

理想情况下,我想一个方法来诠释这使我能(DE)有或没有的getFoo()结果序列化,可能取决于一些配置对象。 这可能吗? 你看到的打算这样做这是一个更好的办法?

Answer 1:

通过观察选项,似乎可以标注属性,如果给定的只显示View传递给ObjectMapper用于序列化。 因此,你可以编辑类:

public static class FooReference {
    public DBRef<Foo> foo;

    @JsonView(Views.WebView.class)
    public Foo getFoo() {
        return foo.fetch();
    }
}

并提供:

class Views {
    static class WebView { }
}

然后创建与正确的视图的配置后序列:

SerializationConfig conf = objectMapper.getSerializationConfig().withView(Views.WebView.class);
objectMapper.setSerializationConfig(conf);

然后将其序列化。 与MongoDB的包装序列化将意味着方法将被忽略时不指定视图。 没有JsonView注解属性默认序列化,可以通过指定改变行为:

objectMapper.configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false);

更多信息可在杰克逊的Wiki 。

还有其他的替代品,也事实证明:有杰克逊混入这将让你重写(反)序列,而无需修改类本身的一类零件的行为,并为杰克逊2.0(最近才发布)的有过滤器了。



Answer 2:

使用自定义JSONSerializer ,并在应用你的逻辑serialize方法:

public static class FooReference {
    public DBRef<Foo> foo;

    @JsonSerialize(using = CustomSerializer.class)
    public Foo getFoo() {
        return foo.fetch();
    }
}

public class CustomSerializer extends JsonSerializer<Object> {
   public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
       throws IOException, JsonProcessingException {
     // jgen.writeObjectField ...
   }
}


文章来源: Serialize one class in two different ways with Jackson