[英]Serialize one class in two different ways with Jackson
In one of our projects we use a java webapp talking to a MongoDB instance. 在我们的一个项目中,我们使用java webapp与MongoDB实例进行通信。 In the database, we use
DBRefs
to keep track of some object relations. 在数据库中,我们使用
DBRefs
来跟踪一些对象关系。 We (de)serialize with POJO objects using jackson (using mongodb-jackson-mapper). 我们使用jackson(使用mongodb-jackson-mapper)使用POJO对象进行序列化。
However, we use the same POJOs to then (de)serialize to the outside world, where our front end deals with presenting the JSON. 但是,我们使用相同的POJO然后(de)序列化到外部世界,我们的前端处理呈现JSON。
Now, we need a way for the serialization for the outside world to contain the referenced object from a DBRef
(so that the UI can present the full object), while we obviously want to have the DBRef
written to the database, and not the whole object. 现在,我们需要一种方法让外部世界的序列化包含来自
DBRef
的引用对象(以便UI可以呈现完整对象),而我们显然希望将DBRef
写入数据库,而不是整个宾语。
Right now I wrote some untested static nested class code: 现在我写了一些未经测试的静态嵌套类代码:
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();
}
}
Ideally I would like a way to annotate this so that I could (de)serialize it either with or without the getFoo() result, probably depending on some configuration object. 理想情况下,我想要一种方法来注释这个,以便我可以(或)使用或不使用getFoo()结果序列化它,可能取决于一些配置对象。 Is this possible?
这可能吗? Do you see a better way of going about doing this?
你有没有看到更好的方法来做这件事?
From looking at options, it seems you can annotate properties to only be shown if a given View
is passed to the ObjectMapper
used for serialization. 通过查看选项,您似乎可以注释属性,只有在给定的
View
传递给用于序列化的ObjectMapper
才会显示。 You could thus edit the class: 你可以编辑这个类:
public static class FooReference {
public DBRef<Foo> foo;
@JsonView(Views.WebView.class)
public Foo getFoo() {
return foo.fetch();
}
}
and provide: 并提供:
class Views {
static class WebView { }
}
and then serialize after creating a configuration with the correct view: 然后在使用正确的视图创建配置后序列化:
SerializationConfig conf = objectMapper.getSerializationConfig().withView(Views.WebView.class);
objectMapper.setSerializationConfig(conf);
Which would then serialize it. 然后将序列化它。 Not specifying the view when serializing with the MongoDB wrapper would mean the method would be ignored.
使用MongoDB包装器进行序列化时不指定视图意味着该方法将被忽略。 Properties without a JsonView annotation are serialized by default, a behaviour you can change by specifying:
默认情况下,没有JsonView批注的属性会被序列化,您可以通过指定以下内容来更改此行为:
objectMapper.configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false);
More info is available on the Jackson Wiki . 更多信息可在Jackson Wiki上获得 。
There are still other alternatives, too, it turns out: there are Jackson MixIns which would let you override (de)serialization behaviour of parts of a class without modifying the class itself, and as of Jackson 2.0 (very recent release) there are filters , too. 还有其他的选择,事实证明:有一些Jackson MixIns可以让你覆盖(de)类的部分行为而不修改类本身,而且从Jackson 2.0(最近的版本)开始就有过滤器也是。
Use a custom JSONSerializer
and apply your logic in the serialize
method: 使用自定义
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 ...
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.