How to make Jersey/Jackson serialize empty list; single element list as an array

匿名 (未验证) 提交于 2019-12-03 02:31:01

问题:

Using Jersey and Jackson to create a REST interface, how do I get List fields to be serialized as a list when there are 0 or 1 elements in them. For example:

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

When bars has no elements, the result serializes as null and when it contains a single element, it serializes as that element, not an array containing a single element. Is there a way to get these to always serialize as an array?

For reference, I'm using Jersey 1.10 and Jackson 1.9.2.

回答1:

I am pretty sure that you are not actually using Jackson ("POJO" variant of JSON serialization), since Jackson would not convert single-element arrays or lists to anything else. So you are probably using one of legacy output methods (like jettison); meaning that if you configure system to use POJO mapping it should just work.



回答2:

I wrote a blog post ages ago about forcing Jersey to serialize single element arrays correctly, not sure if it's out-dated now (its from mid-2010!), but it might be of use.

Note the blog comment from Brill Pappin on the blog demonstrating a different approach which means upgrading the Jettison library that you are using.

In short you can write a custom JaxbContextResolver that looks a little like:

@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;     } } 

For clarity, my payload class looked a little like

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

Regarding stopping Jackson serializing bean properties as null, see my previous answer here, about using annotations to change that behaviour.



回答3:

I managed to solve JSON array "bug" in recent Jersey json library (v1.14 Sep 2012). Secret ingredient is JSONConfiguration and ContextResolver magic. See my following post it has a full code example, customized ContextResolver and rest Application class might be somewhat fuzzy logic in first look.

How to serialize Java primitives using Jersey REST

Primitives and zero or single-element List array are properly serialized to JSON document.



回答4:

Yes, we also faced the same issue. Jackson cannot serialize list with 0 or single element to json array. So we tried to use Json's ObjectMapper to convert POJO object to String. It will serialize java List to json array irrespective of number of elements in List (0 or 1 or > 0). The code would look like :

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

where request is of type Object. This will not affect response. You can give a try.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!