I try to return a list of Strings in Jersey as JSON and XML. I thought this would be trivial.
My first try was to write something like this
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Path("/bar")
public List<String> get() {
return dao.get();
}
and I expected an output similiar to this: ["string1", ..., "stringN] unfortunately I got this:
com.sun.jersey.api.MessageException: A message body writer for Java class java.util.LinkedList, and Java type java.util.List<java.lang.String>, and MIME media type application/json was not found
Then I wrote a wrapper StringList for List
@XmlRootElement
public class StringList {
private List<String> data;
public StringList() {
}
public StringList(List<String> data) {
this.data = data;
}
public List<String> getData() {
return data;
}
public void setData(List<String> data) {
this.data = data;
}
}
and modified the facade to
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Path("/foo")
public StringList stringlist() {
return new StringList(sl());
}
Which works great for Lists with more items than 1.
{"data":["foo","bar"]}
Unfortunately I get two unexepected results for one or zero elements
{"data": "just one"} // for one element i would expect {"data": ["just one"]}
null // for no elements i would expect {"data": []}
Am I doing something completly wrong? How can I fix this?
In order to convince Jersey to output lists the way you want to, you need to provide an own ContextResolver:
This way lists will appear the way you want them to.
NOTE: One downside of this approach is that you need to maintain one additional spot in your code; in case you want to add another (list wrapper) class to your REST interface, you need to remember to go to above code and add that class in your ContextResolver...
My solution to this was a wrapper class (found it somewhere). It works now. I don't understand the thoughts behind not supporting javas List class as a root element. Perhaps it has to do with some json specification / best practice i'm not aware of.
But for now im using this:
You could use
javax.ws.rs.core.GenericEntity
:Okay, I could fix it by searching the samples
This does work, but it can only be used for JSON and not for XML
Fixes problem, but is there also a generic approach?
In addition to the provided answers, if you still get
MessageBodyWriter not found
, try adding a dependency such as:You need to use the alternative JSON configuration
JSONConfiguration.natural()
.Best you create your own
ContextResolver
using that alternative configuration as a provider and tell it which classes it is responsible for.I am unaware of a method to use the alternative configuration globally in another way.