7

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

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

现在,我们需要一种外部世界的序列化方法来包含来自 a 的引用对象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();
    }
}

理想情况下,我想要一种对此进行注释的方法,以便我可以(反)序列化它,无论是否有 getFoo() 结果,可能取决于某些配置对象。这可能吗?你有没有更好的方法来做这件事?

4

2 回答 2

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);

更多信息可在 Jackson Wiki 上找到。

事实证明,还有其他选择:有Jackson MixIns,它可以让您在不修改类本身的情况下覆盖(反)序列化部分类的行为,并且从 Jackson 2.0(最新版本)开始,有过滤器, 也。

于 2012-08-27T12:48:40.097 回答
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 ...
   }
}
于 2012-08-27T12:10:47.133 回答