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:
我正在做一个项目,用Jersey把对象转换成JSON。我希望能够写出嵌套列表,如下所示:
{"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:
这是我的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;
}
}
3 个解决方案
#1
5
Have you tried jersey-json ??
你试过jersey-json吗?
Add jersey-json to your classpath (or your maven dependencies)
将jersey-json添加到类路径(或您的maven依赖项)
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)
在你的ressources中只需要这样的东西(假设DetailProduit是你想要序列化的对象,然后是DetailProduit。java被标记为jaxb,并且在package.of.your.model中)
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/{code}")
public DetailProduit getDetailProduit(@PathParam("code") String code) {
.... Your Code ........
}
#2
1
Check out the "Improving the Application" section of this page:
查看本页的“改善申请”部分:
http://blogs.oracle.com/enterprisetechtips/entry/configuring_json_for_restful_web
http://blogs.oracle.com/enterprisetechtips/entry/configuring_json_for_restful_web
#3
0
I know the qustion is rather old but I stumbled on a similar problem but I wanted to render a List of Arrays ie.´List´ due to a result from a db which I got from jpa and a nativ query without using Entities.
我知道qustion是相当古老的,但我偶然发现了一个类似的问题,但我想呈现一个数组ie列表。´列表´由于结果从db我从jpa和nativ查询不使用实体。
This is how I solved it:
我就是这样解决的:
First Created a ListWrapper.java:
首先创建了一个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);
}
}
And then I created a class extending AbstractMessageReaderWriterProvider
然后我创建了一个扩展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<ListWrapper> {
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<ListWrapper> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> 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<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
final Iterator<Object[]> 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);
}
}
}
Then I using it in a as this:
然后我用a表示
@GET
@Path("/{id}/search")
@Produces(JSON)
public ListWrapper search(@PathParam("id") Integer projectId ) {
return DatabaseManager.search(projectId);
}
The search method is returning a Listwrapper with a list of Object[]
搜索方法返回一个Listwrapper,其中包含一个对象列表[]
Hope this helps someone :-)
希望这能帮助某人:
#1
5
Have you tried jersey-json ??
你试过jersey-json吗?
Add jersey-json to your classpath (or your maven dependencies)
将jersey-json添加到类路径(或您的maven依赖项)
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)
在你的ressources中只需要这样的东西(假设DetailProduit是你想要序列化的对象,然后是DetailProduit。java被标记为jaxb,并且在package.of.your.model中)
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/{code}")
public DetailProduit getDetailProduit(@PathParam("code") String code) {
.... Your Code ........
}
#2
1
Check out the "Improving the Application" section of this page:
查看本页的“改善申请”部分:
http://blogs.oracle.com/enterprisetechtips/entry/configuring_json_for_restful_web
http://blogs.oracle.com/enterprisetechtips/entry/configuring_json_for_restful_web
#3
0
I know the qustion is rather old but I stumbled on a similar problem but I wanted to render a List of Arrays ie.´List´ due to a result from a db which I got from jpa and a nativ query without using Entities.
我知道qustion是相当古老的,但我偶然发现了一个类似的问题,但我想呈现一个数组ie列表。´列表´由于结果从db我从jpa和nativ查询不使用实体。
This is how I solved it:
我就是这样解决的:
First Created a ListWrapper.java:
首先创建了一个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);
}
}
And then I created a class extending AbstractMessageReaderWriterProvider
然后我创建了一个扩展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<ListWrapper> {
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<ListWrapper> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> 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<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
final Iterator<Object[]> 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);
}
}
}
Then I using it in a as this:
然后我用a表示
@GET
@Path("/{id}/search")
@Produces(JSON)
public ListWrapper search(@PathParam("id") Integer projectId ) {
return DatabaseManager.search(projectId);
}
The search method is returning a Listwrapper with a list of Object[]
搜索方法返回一个Listwrapper,其中包含一个对象列表[]
Hope this helps someone :-)
希望这能帮助某人: