如何使用Jersey将嵌套列表编组为JSON? 我得到一个空数组或一个包含数组的单元素字典数组

我正在开发一个使用Jersey将对象转换为JSON的项目。 我希望能够写出嵌套列表,如下所示:

{"data":[["one", "two", "three"], ["a", "b", "c"]]} 

我想要转换的对象首先将数据表示为<LinkedList <LinkedList >>,我认为Jersey会做正确的事情。 以上输出为空值列表:

 {"data":[null, null]} 

在阅读了需要包装的嵌套对象之后,我尝试了以下方法:

 @XmlRootElement(name = "foo") @XmlType(propOrder = {"data"}) public class Foo { private Collection data = new LinkedList(); @XmlElement(name = "data") public Collection 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 data = new LinkedList(); @XmlElement public Collection getData() { return data; } } } 

该代码输出下面的内容,这更接近我想要的内容:

 {"data":[{"data":["one", "two", "three"]},{"data":["a", "b", "c"]}]} 

我希望第一个数据是列表列表,而不是单元素字典列表。 我该如何实现这一目标?

这是我的JAXBContentResolver:

 @Provider public class JAXBContextResolver implements ContextResolver { 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 jsonArray = new HashSet(1) { { add("data"); } }; public JAXBContextResolver() throws Exception { Map props = new HashMap(); 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; } } 

你试过jersey-json吗?

将jersey-json添加到您的类路径(或您的maven依赖项)

然后用这个:

 @Provider public class JAXBContextResolver implements ContextResolver { 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; } } 

你只需要在你的资源中使用这样的东西(假设DetailProduit是你要序列化的对象,而且DetailProduit.java是jaxb标记的,并且在package.of.your.model中)

 @GET @Produces(MediaType.APPLICATION_JSON) @Path("/{code}") public DetailProduit getDetailProduit(@PathParam("code") String code) { .... Your Code ........ } 

我知道qustion相当陈旧,但我偶然发现了一个类似的问题,但我想渲染一个数组列表ie.’List’,因为我从jpa得到的数据库结果和不使用实体的nativ查询。

这就是我解决它的方式:

首先创建一个ListWrapper.java:

 import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class ListWrapper extends ArrayList { @SuppressWarnings("unchecked") public ListWrapper() { super(); } public ListWrapper(List list) { super(list); } } 

然后我创建了一个扩展AbstractMessageReaderWriterProvider的类

 import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider; @Provider @Produces("*/*") @Consumes("*/*") public class ListObjectArrayMessagereaderWriterProvider extends AbstractMessageReaderWriterProvider { public boolean supports(Class type) { return type == ListWrapper.class; } @Override public boolean isReadable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { return type == ListWrapper.class; } @Override public ListWrapper readFrom(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { throw new IllegalArgumentException("Not implemented yet."); } @Override public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { return type == ListWrapper.class; } @SuppressWarnings("unchecked") @Override public void writeTo(ListWrapper t, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { final Iterator iterator = t.iterator(); OutputStreamWriter writer = new OutputStreamWriter(entityStream, getCharset(mediaType)); final JSONArray jsonArrayOuter = new JSONArray(); while (iterator.hasNext()) { final Object[] objs = iterator.next(); JSONArray jsonArrayInner = new JSONArray(Arrays.asList(objs)); jsonArrayOuter.put(jsonArrayInner); } try { jsonArrayOuter.write(writer); writer.write("\n"); writer.flush(); } catch (JSONException je) { throw new WebApplicationException(new Exception(ImplMessages.ERROR_WRITING_JSON_ARRAY(), je), 500); } } } 

然后我在这里使用它:

  @GET @Path("/{id}/search") @Produces(JSON) public ListWrapper search(@PathParam("id") Integer projectId ) { return DatabaseManager.search(projectId); } 

搜索方法返回一个Listwrapper,其中包含Object []列表

希望这有助于某人:-)