When a list has only one item, CXF returns an object instead of a js array

I use CXF to create cool services. One of the services returns a list of strings. When I have more than one element in the list, CXF returns an array of strings, but when I have only one element, it returns String instead of an array with json:

With one element:

{"ImageResponse":{"images":"hello"}} 

With two elements:

  {"ImageResponse":{"images":["hello","hi"]}} 

Is there a way to always return a list, even if there is only one item in the list?

My Response Class:

 @XmlRootElement public class ImageResponse { private List<String> images; //getter and setter } 
+4
source share
5 answers

Try setting 'serializeAsArray' as true in your cxf json provider. See http://cxf.apache.org/docs/jax-rs-data-bindings.html

+5
source

The above problem occurs when you use Jettison to serialize JSON. Jettison is used by default in CXF. The easiest way to achieve your requirement is to change your JSON provider to Jackson. There you do not need to install serializeAsArray and mention arrayKeys for each arrayKeys box!

Add the following to the beans definition:

 <jaxrs:providers> <bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider"/> </jaxrs:providers> 

Then add the Jackson library. The maven pom dependency is as follows:

 <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-jaxrs</artifactId> <version>1.9.0</version> </dependency> 

See here for more information: http://cxf.apache.org/docs/jax-rs-data-bindings.html#JAX-RSDataBindings-Jackson

+1
source

Add the dependency below.

  <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-jaxrs</artifactId> <version>1.9.0</version> </dependency> 

Convert the object to json string using below in your code.

 ObjectMapper mapperObj = new ObjectMapper(); String jsonStr = ""; try { // get the object as a json string jsonStr = mapperObj.writeValueAsString(imageResponse ); //System.out.println(jsonStr); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

Now use this string instead of Object (convert this string object to JSON using CXF (for example, how you do this for an object))

 return Response.status(201).entity(jsonStr).build(); 
+1
source

had a similar situation. cxf does not return the array of arrays requested by js, it adds an additional tag "item" additionally. When changing to applicationContext.xml add jsonProvider and send it to jaxrs.

 <jaxrs:server id="someid" address="/"> <jaxrs:providers> <ref bean="jsonProvider" /> </jaxrs:providers> <bean id="jsonProvider" lass="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider"> <property name="mapper" ref="jsonMapper" /> </bean> <bean id="jsonMapper" class="com.bofa.idp.disclosures.CustomJsonMapper" /> 

...

in customJsonMapper extends ObjectMpper and can perform customization

 public CustomJsonMapper() { super(); enable(DeserializationFeature.UNWRAP_ROOT_VALUE); enable(SerializationFeature.WRAP_ROOT_VALUE); enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); JaxbAnnotationModule jaxbModule=new JaxbAnnotationModule(); this.registerModule(jaxbModule); this.setSerializationInclusion(JsonInclude.Include.NON_NULL); this.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); } 
0
source

Your first JSON does not contain a single-element list.

If you want the images to be an array, you need to use square brackets.

{"ImageResponse": {"images": ["Hello"] }}

-3
source

All Articles