Jackson,如何在序列化扩展 collection 的 class 时公开字段?
Jackson, how to expose fields when serializing a class which extend a collection?
我有一个 class 用于分页结果,如下所示:
public class PaginatedList<T> extends LinkedList<T> {
private int offset;
private int count;
private int totalResultCount;
//...
}
我希望 Jackson 像这样连载它:
{
"results":[1,2,3],
"offset":0,
"count":3,
"totalResultCount":15
}
(其中 parent 列表包含三个整数值 1,2 和 3。)
在我的第一次尝试中,我发现 Jackson 有效地忽略了 classes 上可分配给 Collection class 的任何属性。事后看来,这是有道理的,所以我现在正在寻找解决方法。搜索 SO 得到两个类似的问题:
- jackson-serialization-includes-subclasss-fields
- jaxb-how-to-serialize-fields-in-a-subclass-of-a-collection
然而,这两者都导致了从继承切换到组合的建议。
我正在专门寻找 允许 class 扩展 collection 的解决方案。这个 'PaginatedList' class 是企业共同核心的一部分,并扩展了 Collection 以便它可以在整个代码中用作(和自省)作为 collection。更改为组合不是一种选择。话虽这么说,我可以随意注释和更改此 class 以支持如上所述的序列化。
因此,据我所知,我缺少两个部分(我在答案中寻找的内容):
- 如何让 Jackson 获得 'see' 添加的属性?
- 如何让 Jackson 在 JSON 输出中将 collection 的内容标记为 'results' 属性?
(PS: 我只关心序列化。)
Ashley Frieze 在评论中指出了这一点,这个回答值得称赞。
我通过如下创建 JsonSerializer 实例解决了这个问题:
public class PaginatedListSerializer extends JsonSerializer<PaginatedList> {
@Override
public Class<PaginatedList> handledType() {
return PaginatedList.class;
}
@Override
public void serialize(PaginatedList value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeArrayFieldStart("results");
for (Object entry : value) {
jgen.writeObject(entry);
}
jgen.writeEndArray();
jgen.writeNumberField("offset", value.offset);
jgen.writeNumberField("count", value.count);
jgen.writeNumberField("totalResultCount", value.totalResultCount);
jgen.writeEndObject();
}
}
当然,将其注册为模块:
SimpleModule testModule = new SimpleModule("PaginatedListSerializerModule", new Version(1, 0, 0, null, null, null));
testModule.addSerializer(new PaginatedListSerializer());
mapper.registerModule(testModule);
我有一个 class 用于分页结果,如下所示:
public class PaginatedList<T> extends LinkedList<T> {
private int offset;
private int count;
private int totalResultCount;
//...
}
我希望 Jackson 像这样连载它:
{
"results":[1,2,3],
"offset":0,
"count":3,
"totalResultCount":15
}
(其中 parent 列表包含三个整数值 1,2 和 3。)
在我的第一次尝试中,我发现 Jackson 有效地忽略了 classes 上可分配给 Collection class 的任何属性。事后看来,这是有道理的,所以我现在正在寻找解决方法。搜索 SO 得到两个类似的问题:
- jackson-serialization-includes-subclasss-fields
- jaxb-how-to-serialize-fields-in-a-subclass-of-a-collection
然而,这两者都导致了从继承切换到组合的建议。
我正在专门寻找 允许 class 扩展 collection 的解决方案。这个 'PaginatedList' class 是企业共同核心的一部分,并扩展了 Collection 以便它可以在整个代码中用作(和自省)作为 collection。更改为组合不是一种选择。话虽这么说,我可以随意注释和更改此 class 以支持如上所述的序列化。
因此,据我所知,我缺少两个部分(我在答案中寻找的内容):
- 如何让 Jackson 获得 'see' 添加的属性?
- 如何让 Jackson 在 JSON 输出中将 collection 的内容标记为 'results' 属性?
(PS: 我只关心序列化。)
Ashley Frieze 在评论中指出了这一点,这个回答值得称赞。
我通过如下创建 JsonSerializer 实例解决了这个问题:
public class PaginatedListSerializer extends JsonSerializer<PaginatedList> {
@Override
public Class<PaginatedList> handledType() {
return PaginatedList.class;
}
@Override
public void serialize(PaginatedList value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeArrayFieldStart("results");
for (Object entry : value) {
jgen.writeObject(entry);
}
jgen.writeEndArray();
jgen.writeNumberField("offset", value.offset);
jgen.writeNumberField("count", value.count);
jgen.writeNumberField("totalResultCount", value.totalResultCount);
jgen.writeEndObject();
}
}
当然,将其注册为模块:
SimpleModule testModule = new SimpleModule("PaginatedListSerializerModule", new Version(1, 0, 0, null, null, null));
testModule.addSerializer(new PaginatedListSerializer());
mapper.registerModule(testModule);