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

时间:2011-11-21 16:13:19

标签: java json jersey jackson

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

@XmlRootElement(name="foo")
public class Foo {
  @XmlElement
  public List<Bar> getBars() {
    return this.bars;
  }
}

@Path("foo")
public FooResource {
  @GET
  public Foo getFoo() {
    return theFoo;
  }
}

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

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

4 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:3)

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

请注意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,请参阅my previous answer here, about using annotations to change that behaviour.

答案 2 :(得分:1)

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

How to serialize Java primitives using Jersey REST

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

答案 3 :(得分:0)

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

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

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