2009-07-17 6 views
8

Jerseyを使用してオブジェクトをJSONに変換するプロジェクトに取り組んでいます。Jerseyを使用してネストされたリストをJSONとしてマーシャリングするにはどうすればよいですか? nullの配列または配列を含む1要素の辞書の配列を取得します。

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

私が最初に変換< LinkedListの< LinkedListの<文字列> > >などのデータを表現したいオブジェクト、と私はジャージーを考え出し:私はそうのように、ネストされたリストを書き出すことができるようにしたいのですが正しいことをするだけだろう。上記は、ヌルのリストとして出力されました:ネストされたオブジェクトをラップする必要があることを読んだ後

{"data":[null, null]} 

、私は次のことを試してみました:

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

コードは何に近いある、下記何出力します私がしたい:

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

は私が最初のデータはリストのリストではなく、1要素の辞書のリストになりたいです。これをどのように達成するのですか?

は、ここに私のJAXBContentResolverです:あなたはジャージー-JSONを試してみました

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

答えて

5

はその後、この使用あなたのクラスパス(またはあなたのMavenの依存関係)にジャージ-JSONを追加します。

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

} 

あなただけのressourcesでこのような何かを必要とする(想定DetailProduitは、あなたのオブジェクトである、あなたがしたいですこの「アプリケーションの改善」のセクションをご覧ください

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

あなたのケースは私よりも複雑だったと思っています... – Arnaudweb

0

私はqustionはかなり古いです知っているが、私は同様の問題につまずいたが、私は、私はからもらったDBから起因する結果に配列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<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); 
     } 
    } 
} 

を拡張するクラスを作成しました:

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

検索方法は、リストでListwrapperを返しますオブジェクト[]

これは誰かに役立つことを願っています:-)

関連する問題