2012-12-10 11 views
7

Sto scrivendo un servizio REST utilizzando Jersey. Ho una promozione classe astratta che ha un'annotazione:@JsonTypeInfo (use = JsonTypeInfo.Id.CLASS) non funziona quando viene restituita la risposta

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) 

Grazie a ciò, quando torno un elenco di oggetti:

@GET 
@Produces(MediaType.APPLICATION_JSON) 
@Path("promotions/") 
public List<Promotion> getClosestPromotions() { 
List<Promotion> promotions = getPromotions(); //here I get some objects 

return promotions; 
} 

ottengo una stringa JSON con un campo "@class" per ogni oggetto in quella lista. Ma il problema è che se restituire una risposta:

@GET 
@Produces(MediaType.APPLICATION_JSON) 
@Path("promotions/") 
public Response getClosestPromotions() { 
List<Promotion> promotions = getPromotions(); //here I get some objects 

return Response.ok().entity(promotions).build(); 
} 

sto ottenendo quasi la stessa lista, ma senza ulteriore campo "@class". Perché è questo e cosa posso fare per ottenere una lista con il campo "@class" che restituisce una lista in Risposta? E a proposito, sorprendentemente, funziona quando restituisco una risposta con un oggetto di promozione dato solo come entità e ottengo quel campo "@class".

+1

Non ho sufficiente per una risposta ancora, ma. Il metodo entità accetta un oggetto. Il codice sottostante controlla probabilmente il tipo in fase di runtime per ripristinare le informazioni sul tipo. Sfortunatamente questo lo otterrà fino alla lista e non alla lista . Lo scrive come una lista senza informazioni di tipo generico, quindi perderesti il ​​campo della classe. Scrivere un oggetto che ha la lista come variabile membro probabilmente funzionerà, ma sto cercando di trovare qualcosa di più pulito. –

risposta

5

Forse si vorrebbe provare:

GenericEntity<Collection<Promotion>> genericEntity = 
      new GenericEntity<Collection<Promotion>>(promotions){}; 
return Response.ok().entity(genericEntity).build(); 
+1

Grazie mille! Finalmente ho funzionato! – krajol

+1

Questa è una soluzione semplice che funziona molto bene, grazie per averlo condiviso! L'unico lato negativo è che dobbiamo ricordare di avvolgere le nostre collezioni in questo modo tutto il tempo. –

2

Prova ad aggiungere l'annotazione sottotipi, ecco un esempio che sto usando. Questo potrebbe risolvere il tuo problema specificando tutti i sottotipi operabili. Spiacente, non ho testato il tuo esatto esempio.

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class") 
@JsonSubTypes({ 
    @JsonSubTypes.Type(value=MetricCollection.class), 
    @JsonSubTypes.Type(value=Column.class), 
    @JsonSubTypes.Type(value=IntegerColumn.class), 
    @JsonSubTypes.Type(value=DoubleColumn.class), 
    @JsonSubTypes.Type(value=StringColumn.class) 
}) 
public interface IMetricCollection<T extends IMetric> { 
... 
} 
0

Se è stato utilizzato JAXB per generare le vostre classi, si può certamente avere qualcosa di simile @XmlElements con diversi tipi di analizzare un elenco.

Ora, se si utilizzano anche le stesse classi JAXB con Jersey/Jackson, è possibile migliorare i metadati della classe aggiungendo @JsonTypeInfo e @JsonSubTypes per descrivere come formattare il nome della lista/matrice di oggetti.

Mentre @JsonTypeInfo descrive il tipo da aggiungere, @JsonSubTypes fornisce le opzioni della raccolta chiusa. Ad esempio, As.PROPERTY per definire una proprietà dell'output, come visualizzato nell'esempio seguente, in cui un elenco di entità che possono avere elementi di tipi diversi, incluso il tipo stesso ("Form") oltre a 2 altri tipi " Campo "e" Tabella ".

public class Form { 

    @XmlElements({ 
    @XmlElement(name = "field", type = Field.class), 
    @XmlElement(name = "form", type = Form.class), 
    @XmlElement(name = "table", type = Table.class) 
    }) 
    @JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "obj") 
    @JsonSubTypes({ 
    @JsonSubTypes.Type(value = Field.class), 
    @JsonSubTypes.Type(value = Form.class), 
    @JsonSubTypes.Type(value = Table.class) 
    }) 
    @Generated(value = "com.sun.tools.internal.xjc.Driver", date = "2013-11-11T02:08:36-08:00", comments = "JAXB RI v2.2.4-2") 
    @JsonProperty("entities") 
    protected List<Object> fieldOrFormOrTable; 

La serializzazione degli oggetti utilizzando Jackson serializzatori di default di Jersey con i metadati aggiunta sarà il seguente ...

 "entities": [ 
        { 
        "obj": "Table", 
        "row": { 
         "id": 1, 
         "fields": [ 
          { 
           "id": "DEBUGARY", 
           "type": "Text", 
           "kind": "user" 
          } 
         ] 
        }, 
        "id": "DBGARRAY" 
       }, 
       { 
        "obj": "field", 
        "id": "IDBG", 
        "type": "Text", 
        "kind": "user" 
       }, 
     ..., ..., ...] 
Problemi correlati