如何让泽西/jackson序列化空列表; 单个元素列表作为数组

使用Jersey和Jackson创建REST接口,如果列表中包含0或1个元素,如何将列表字段序列化为列表。 例如:

@XmlRootElement(name="foo") public class Foo { @XmlElement public List getBars() { return this.bars; } } @Path("foo") public FooResource { @GET public Foo getFoo() { return theFoo; } } 

当bars没有元素时,结果序列化为null ,当它包含单个元素时,它序列化为该元素,而不是包含单个元素的数组。 有没有办法让这些始终序列化为数组?

作为参考,我使用Jersey 1.10和Jackson 1.9.2。

我很确定你实际上并没有使用Jackson(JSON序列化的“POJO”变体),因为Jackson不会将单元素数组或列表转换为其他任何东西。 所以你可能正在使用一种传统的输出方法(如jettison); 这意味着如果您将系统配置为使用POJO映射,它应该可以正常工作。

我在很久以前写了一篇关于强迫泽西岛正确序列化单个元素数组的博客文章,不确定它现在已经过时了(它从2010年中期开始!), 但它可能有用。

请注意Brill Pappin在博客上发表的博客评论,演示了一种不同的方法,这意味着升级您正在使用的Jettison库。

简而言之,您可以编写一个看起来有点像的自定义JaxbContextResolver:

 @Provider @Component public class JAXBContextResolver implements ContextResolver { private JAXBContext context; public JAXBContextResolver() throws Exception { MappedBuilder builder = JSONConfiguration.mapped(); builder.arrays("invite"); builder.rootUnwrapping(true); this.context = new JSONJAXBContext(builder.build(), Payload.class); } public JAXBContext getContext(Class objectType) { return (Payload.class.equals(objectType)) ? context : null; } } 

为清楚起见,我的有效载荷类看起来有点像

 @XmlRootElement(name = "response") @XmlAccessorType(XmlAccessType.FIELD) public class Payload { @XmlElement(name = "invite") List invites; ... etc. 

关于将Jackson序列化bean属性停止为null,请参阅我之前的回答,关于使用注释来改变该行为。

我设法在最近的Jersey json库中解决了JSON数组“bug”(2012年9月1日至14日)。 秘密成分是JSONConfiguration和ContextResolver魔法。 请参阅我的以下post,它有一个完整的代码示例,自定义的ContextResolver和其他Application类可能在初看起来有点模糊逻辑。

如何使用Jersey REST序列化Java基元

基元和零或单元素列表数组已正确序列化为JSON文档。

是的,我们也遇到了同样的问题。 jackson无法将带有0或单个元素的列表序列化为json数组。 所以我们尝试使用Json的ObjectMapper将POJO对象转换为String。 它将java List序列化为json数组,而不管List(0或1或> 0)中的元素数量。 代码看起来像:

  request = new ObjectMapper().writeValueAsString(pojo); 

其中request是Object类型。 这不会影响响应。 你可以尝试一下。