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

时间:2012-08-27 11:59:19

标签: java mongodb jackson pojo mongo-jackson-mapper

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

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

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

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

DBRef

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

2 个答案:

答案 0 :(得分:8)

通过查看选项,似乎只有在将给定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);

有更多信息on the Jackson Wiki

还有其他选择,事实证明:有Jackson MixIns可以让你覆盖(de)类部分的序列化行为而不修改类本身,并且从Jackson 2.0开始(非常最近发布的)也有filters

答案 1 :(得分: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 ...
   }
}