问题
I'm using CXF to create restful services. One of the services return a list of string. When I have more than one item in the list, the CXF returns an array of strings, but when I have only one element, it returns the String instead an array with a json:
With one Item:
{"ImageResponse":{"images":"hello"}}
With two Items:
{"ImageResponse":{"images":["hello","hi"]}}
Is there a way to always return a list, even when the list has only one item?
My Response class:
@XmlRootElement
public class ImageResponse {
private List<String> images;
//getter and setter
}
回答1:
Try setting 'serializeAsArray' as true on your cxf json provider. Refer : http://cxf.apache.org/docs/jax-rs-data-bindings.html
回答2:
The above said issue is there when you use Jettison for JSON serialization. Jettison is the default in CXF. The easiest way to achieve your requirement is to change the JSON Provider to Jackson. There, you do not have to set serializeAsArray
, and mention the arrayKeys
for each and every field with lists!
Add the following to your beans definition:
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider"/>
</jaxrs:providers>
Then, add include 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 info: http://cxf.apache.org/docs/jax-rs-data-bindings.html#JAX-RSDataBindings-Jackson
回答3:
Add below dependency.
<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 itself.
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 the Object (convert this string object to JSON using CXF(like currently how you are doing for the object))
return Response.status(201).entity(jsonStr).build();
回答4:
had a similar situation. cxf does not return array of array that js side requested, it adds some "item" tag additionally. Had to change in applicationContext.xml, add jsonProvider and refer it in 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 do adjustment
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);
}
individual service can be adjust to not use global settings defined in CustomeJsonMapper @JsonFormat(without = JsonFormat.Feature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED)
回答5:
Your first JSON does not contain a list with one item.
If you want images to be an array you have to use square brackets.
{"ImageResponse":{"images":["hello"]}}
来源:https://stackoverflow.com/questions/18918091/when-a-list-has-only-one-element-cxf-return-the-object-instead-a-js-array