2012-06-10 12 views
29

ho 2 classi:Escludendo campi in JAXB

@XmlRootElement 
public class A { 

    private Long id; 
    private B b; 

    // setters and getters 
} 

e

@XmlRootElement 
public class B { 

    private Long id; 
    private String field1; 
    private String field2; 

    // setters and getters 
} 

Per impostazione predefinita, se trasformo un'istanza della classe A al codice XML, avrò tutti i suoi campi (id) ed i campi di riferimento B classe (id, field1, field2) come questo:

<a> 
    <id>2</id> 
    <b> 
     <id>5</id> 
     <field1>test1</field1> 
     <field2>test3</field2> 
    </b> 
</a> 

È possibile modificare quali campi della classe di riferimento B sono inclusi nel codice XML della classe A? Per esempio. Voglio dire che quando trasformo un'istanza della classe A, voglio solo ottenere id dal B Class (senza field1 e field2 campi), quindi voglio ottenere:

<a> 
    <id>2</id> 
    <b> 
     <id>5</id> 
    </b> 
</a> 

Non voglio per annotare in modo permanente la classe B (usando @XMLTransient o @XMLElement) per realizzarlo, in quanto vi sono casi in cui voglio esportare tutta la B classe come è (con id, field1 e field2.)
io proprio non si vuole esportare tutti questi campi quando la classe B è referenziato da A.

Questo è possibile anche con JAX-B?

risposta

7

I binding JAXB predefiniti possono essere sovrascritti a livello globale o caso per caso, in base alle esigenze, utilizzando custom binding declarations o utilizzare @XmlTransient sul campo.

+0

Grazie! Immagino che complichi le cose un po 'se sto usando l'implementazione di Glassfish JAXB ... Sembra che non ci sia una soluzione basata su annotazioni e ho bisogno di creare un ulteriore XML di personalizzazione? –

86

È possibile utilizzare l'annotazione @XmlTransient per ignorare i campi. Metti questa annotazione sul campo stesso o sul suo getter.

+0

Dove dovrei inserirlo? Nei campi 'campo1' e' campo2' '' B'? Non causerebbe la rimozione di 'field1' e' field2' da quando si trasforma ** un'istanza di 'B' class **? –

+0

Dovresti mettere queste annotazioni su campi o metodi della classe B. I campi di non saranno rimossi.Semplicemente non appariranno nel risultato XML – AlexR

+1

Grazie Alex, ma penso che sia esattamente la cosa che non voglio fare (fai riferimento all'ultimo paragrafo della mia domanda). Questa modifica impedirà che i campi vengano visualizzati nell'XML risultante in ** tutte le occorrenze ** della classe B. –

12

Ok, mi è venuta in mente qualche soluzione hacky:

@XmlRootElement 
public class A { 

    private Long id; 
    private B b; 

    // setters and getters 
} 

ho fornito un getter aggiuntivo solo per il caso d'uso REST, quindi è come:

@XMLTransient 
public B getB() { 
    return b; 
} 

@XMLElement(name="b") 
public Long getBForREST() { 
    return b.getId(); 
} 

risulta nella seguente struttura:

<a> 
    <id>2</id> 
    <b>5</b> 
</a> 

non è esattamente stessa struttura ho mirato per funziona per me.

Non mi piace questa soluzione: uno @XMLExclude({"field1", "field2"}) o qualcosa del genere sarebbe molto più pulito a mio parere.

Tuttavia, per ora funziona; è brutto, ma funziona.

+3

È persino possibile rendere privato il getter REST-only, in modo da non confondere gli utenti della classe. –

+0

Non è brutto, è perfetto, grazie! –