可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.