'Return List<String> in REST Web Service

How can return List of Strings in REST Web Services

I am using CXF 2.7.8

I have one method as :

    @GET
@Path("/items")
@Produces(MediaType.APPLICATION_JSON)
public List<String> getItems() {
    List<String> list = service.getList();
    return list;
}

I am getting error as "No message body writer has been found for response class ArrayList."

Option 1

I have also tried to use GenericEntity> and got same error as above

Option 2

I have also created Wrapper class for list as

@XmlRootElement(name = "listWarpper")
public class ListWarpper implements Serializable {

private static final long serialVersionUID = 1L;

private List<String> list;

public ListWarpper() {
}

public ListWarpper( List<String> list ) {
    this.list = list;
}

public List<String> getList() {
    return list;
}

public void setList( List<String> list ) {
    this.list = list;
}

}

and it works fine but only problem with it is when result have just one item into list then returned json is

{ list: "Only one Item"}

instead of `{list : ["Only one Item"]}

My problem is how can I get returning json in form of as follows no matter if list is empty or containing just one element

{ list : [...]}

or {[...]}



Solution 1:[1]

After searching for sometime I found solution for option 2.

I need to configure "serializeAsArray" and "arrayKeys".

I my case it as following

        <property name="serializeAsArray" value="true" />

        <property name="arrayKeys">
         <list>
          <value>list</value>
         </list>
        </property> 

More detail http://cxf.apache.org/docs/jax-rs-data-bindings.html#JAX-RSDataBindings-DealingwithJettisonarrayserializationissues

Solution 2:[2]

You can create JAXB as follows.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "mylist"
})
@XmlRootElement(name = "kplist")
public class Kplist {

    @XmlElement(required = true)
    protected List<String> mylist;


    public List<String> getMylist() {
        if (mylist == null) {
            mylist = new ArrayList<String>();
        }
        return this.mylist;
    }

}

ObjectFactory.java

@XmlRegistry
public class ObjectFactory {

    public ObjectFactory() {
    }

    public Kplist createKplist() {
        return new Kplist();
    }

}

package-info.java

@javax.xml.bind.annotation.XmlSchema(namespace = "", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.kp.schema;

cx-bean.xml

<jaxrs:server id="KPService" address="/KPApp">
        <jaxrs:serviceBeans>
            <ref bean="kpBean" />
        </jaxrs:serviceBeans>
        <jaxrs:providers>

            <bean class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
                <property name="dropRootElement" value="true" />
                <property name="dropCollectionWrapperElement" value="false" />
                <property name="ignoreNamespaces" value="true" />
                <property name="convention" value="mapped" />
                <property name="unmarshallAsJaxbElement" value="true" />
                <property name="writeXsiType" value="false" />
<property name="readXsiType" value="false" />
<property name="serializeAsArray" value="true" />
                <property name="arrayKeys">
                    <list>
                        <value>mylist</value>
                    </list>
                </property>
            </bean>

            <ref bean="schemaGen" />

        </jaxrs:providers>

        <jaxrs:features>
            <cxf:logging />
        </jaxrs:features>

    </jaxrs:server>

    <bean id="kpBean" class="com.rest.KPResource"></bean>

    <bean id="schemaGen" class="org.apache.cxf.jaxrs.model.wadl.WadlGenerator">
        <property name="linkJsonToXmlSchema" value="true" />
        <property name="schemaLocations">
            <list>
                <value>classpath:/json.schema</value>
            </list>
        </property>
        <property name="useJaxbContextForQnames" value="true" />
        <property name="ignoreMessageWriters" value="false" />
        <property name="addResourceAndMethodIds" value="true" />
    </bean>
**Test**

Kplist list = new Kplist();
        list.getMylist().add("KP5");
        return list;

**output**

{"kp1":["KP5"]}

**Note:** 

Below property drops root field

<property name="dropRootElement" value="false" />

Solution 3:[3]

What is the point if you are creating a ListWrapper but not using it. Try this in your get function

@GET
@Path("/items")
@Produces(MediaType.APPLICATION_JSON)
public ListWarpper getItems() {
    List<String> list = service.getList();
    ListWarpper l = new ListWarpper ();
    l.setList(list);
    return l;
}

Solution 4:[4]

You can try to use Jackson Library to write the list of items as a string

return new ObjectMapper().writeValueAsString(items);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mitesh
Solution 2
Solution 3 Chit Khine
Solution 4 mha90