How do I marshal nested lists as JSON using Jersey? I get an array of nulls or an array of one-element dictionaries containing an array
arrays, java, jaxb, jersey, json
Solution
Have you tried jersey-json ??
Add jersey-json to your classpath (or your maven dependencies)
Then use this :
@Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> {
private final JAXBContext context;
public JAXBContextResolver() throws Exception {
this.context = new JSONJAXBContext(JSONConfiguration.natural().build(), "package.of.your.model");
}
public JAXBContext getContext(Class<?> objectType) {
return context;
}
}
You only need something like this in your ressources (supposing DetailProduit is your object you want to serialize and that DetailProduit.java is jaxb tagged and in package.of.your.model)
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/{code}")
public DetailProduit getDetailProduit(@PathParam("code") String code) {
.... Your Code ........
}
Problem
I'm working on a project which uses Jersey to convert objects to JSON. I'd like to be able to write out nested lists, like so: ``` {"data":[["one", "two", "three"], ["a", "b", "c"]]} ``` The object I'd like to convert first represented data as a <LinkedList<LinkedList<String>>>, and I figured Jersey would just do the right thing. The above was output as a list of nulls: ``` {"data":[null, null]} ``` After reading that nested objects need to be wrapped, I tried the following: ``` @XmlRootElement(name = "foo") @XmlType(propOrder = {"data"}) public class Foo { private Collection<FooData> data = new LinkedList<FooData>(); @XmlElement(name = "data") public Collection<FooData> getData() { return data; } public void addData(Collection data) { FooData d = new FooData(); for(Object o: data) { d.getData().add(o == null ? (String)o : o.toString()); } this.data.add(d); } @XmlRootElement(name = "FooData") public static class FooData { private Collection<String> data = new LinkedList<String>(); @XmlElement public Collection<String> getData() { return data; } } } ``` That code outputs what's below, which is closer to what I want: ``` {"data":[{"data":["one", "two", "three"]},{"data":["a", "b", "c"]}]} ``` I want the first data to be a list of lists, not a list of one-element dictionaries. How do I achieve this? Here's my JAXBContentResolver: ``` @Provider public class JAXBContextResolver implements ContextResolver<JAXBContext> { private JAXBContext context; private Set<Class<?>> types; // Only parent classes are required here. Nested classes are implicit. protected Class<?>[] classTypes = new Class[] {Foo.class}; protected Set<String> jsonArray = new HashSet<String>(1) { { add("data"); } }; public JAXBContextResolver() throws Exception { Map<String, Object> props = new HashMap<String, Object>(); props.put(JSONJAXBContext.JSON_NOTATION, JSONJAXBContext.JSONNotation.MAPPED); props.put(JSONJAXBContext.JSON_ROOT_UNWRAPPING, Boolean.TRUE); props.put(JSONJAXBContext.JSON_ARRAYS, jsonArray); this.types = new HashSet<Class<?>>(Arrays.asList(classTypes)); this.context = new JSONJAXBContext(classTyes, props); } public JAXBContext getContext(Class<?> objectType) { return (types.contains(objectType)) ? context : null; } } ```