2009-07-17 7 views
8

Je travaille sur un projet qui utilise Jersey pour convertir des objets en JSON. Je voudrais pouvoir écrire des listes imbriquées, comme suit:Comment rassembler des listes imbriquées en JSON en utilisant Jersey? Je reçois un tableau de zéros ou un tableau de dictionnaires à un élément contenant un tableau

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

L'objet que je voudrais convertir d'abord représenté données en tant que < LinkedList < LinkedList <cordes> > >, et je me suis dit Jersey ferait juste la bonne chose. Ce qui précède était sortie comme une liste de valeurs nulles:

{"data":[null, null]} 

Après avoir lu que les objets imbriqués doivent être emballés, j'ai essayé les éléments suivants:

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

Ce code renvoie ce qui est ci-dessous, qui est plus proche de ce Je veux:

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

Je veux que les premières données soient une liste de listes, pas une liste de dictionnaires à un élément. Comment puis-je y parvenir?

Voici mon 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; 
    } 
} 

Répondre

5

Avez-vous essayé jersey JSON ??

Ajouter maillot JSON à votre classpath (ou vos dépendances de Maven)

Ensuite, utilisez ceci:

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

} 

Vous avez seulement besoin quelque chose comme ceci dans vos ressources (en supposant DetailProduit est votre objet que vous voulez sérialisation et que DetailProduit.java est JAXB étiquetée et package.of.your.model)

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

Ok, je pensais que votre cas était plus complexe que je le pensais ... – Arnaudweb

0

Je sais que le qustion est assez vieux mais je suis tombé sur un problème similaire mais je voulais rendre une liste de tableaux ie.'List' en raison d'un résultat d'une db que je suis arrivé de jpa et une requête nativ sans utiliser d'entités.

Voici comment je l'ai résolu:

d'abord créé un 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); 
    } 
} 

Et puis je crée une classe extension 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); 
     } 
    } 
} 

Puis je l'utiliser dans un comme ceci:

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

La méthode de recherche renvoie une Listwrapper une liste de l'objet []

Espérons que cela aide quelqu'un :-)

Questions connexes