用Jackson以两种不同的方式序列化一个class级

在我们的一个项目中,我们使用java webapp与MongoDB实例进行通信。 在数据库中,我们使用DBRefs来跟踪一些对象关系。 我们使用jackson(使用mongodb-jackson-mapper)使用POJO对象进行序列化。

但是,我们使用相同的POJO然后(de)序列化到外部世界,我们的前端处理呈现JSON。

现在,我们需要一种外部世界的序列化方法来包含来自DBRef的引用对象(以便UI可以呈现完整对象),而我们显然希望将DBRef写入数据库,而不是整个宾语。

现在我写了一些未经测试的静态嵌套类代码:

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

理想情况下,我想要一种方法来注释这个,以便我可以(或)使用或不使用getFoo()结果序列化它,可能取决于某些配置对象。 这可能吗? 你有没有看到更好的方法来做这件事?

通过查看选项,您似乎可以注释属性,只有在给定的View传递给用于序列化的ObjectMapper才会显示。 你可以编辑这个类:

 public static class FooReference { public DBRef 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); 

更多信息可在Jackson Wiki上获得 。

还有其他选择,事实certificate:有一些Jackson MixIns可以让你覆盖(de)类的部分行为而不修改类本身,而且从Jackson 2.0(最近的版本)开始就有filter也是。

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

 public static class FooReference { public DBRef foo; @JsonSerialize(using = CustomSerializer.class) public Foo getFoo() { return foo.fetch(); } } public class CustomSerializer extends JsonSerializer { public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { // jgen.writeObjectField ... } }