2009-07-17 21 views
8

Tôi đang làm việc trên một dự án sử dụng Jersey để chuyển đổi các đối tượng thành JSON. Tôi muốn để có thể viết ra danh sách lồng nhau, như vậy:Làm cách nào để sắp xếp các danh sách lồng nhau dưới dạng JSON bằng Jersey? Tôi nhận được một mảng null hoặc một mảng từ điển một phần tử có chứa một mảng

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

Đối tượng tôi muốn chuyển đổi đầu tiên đại diện cho dữ liệu như một LinkedList < < LinkedList < Chuỗi > > >, và tôi đã tìm Jersey sẽ làm điều đúng đắn. Trên đây là đầu ra như một danh sách các null:

{"data":[null, null]} 

Sau khi đọc rằng đối tượng lồng nhau cần phải được bao bọc, tôi thử như sau:

@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; 
     } 
    } 
} 

Đó là mã kết quả đầu ra những gì bên dưới, đó là gần gũi hơn với những gì Tôi muốn:

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

Tôi muốn dữ liệu đầu tiên là danh sách các danh sách, không phải danh sách từ điển một phần tử. Làm thế nào để đạt được điều này?

Dưới đây là JAXBContentResolver tôi:

@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; 
    } 
} 

Trả lời

5

Bạn đã thử jersey-json ??

Thêm jersey-json để classpath của bạn (hoặc phụ thuộc maven bạn)

Sau đó sử dụng này:

@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; 
    } 

} 

Bạn chỉ cần một cái gì đó như thế này trong ressources của bạn (giả DetailProduit là đối tượng mà bạn muốn tuần tự hóa và rằng DetailProduit.java là jaxb được gắn thẻ và trong package.of.your.model)

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

Ok, tôi chỉ đoán trường hợp của bạn phức tạp hơn tôi ... – Arnaudweb

0

Tôi biết qustion là khá cũ nhưng tôi vấp vào một vấn đề tương tự nhưng tôi muốn làm một Danh sách Mảng ie.'List' do Kết quả là từ một db mà tôi nhận được từ jpa và truy vấn nativ mà không sử dụng thực thể.

Đây là cách tôi đã giải quyết:

Lần đầu tiên tạo danh sáchWelpper.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); 
    } 
} 

Và sau đó tôi đã tạo ra một lớp mở rộng 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); 
     } 
    } 
} 

Sau đó, tôi sử dụng nó trong một như thế này:

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

Phương pháp tìm kiếm được trả lại một Listwrapper với một danh sách của Object []

Hy vọng điều này sẽ giúp ai đó :-)

Các vấn đề liên quan