2013-03-06 22 views
7

Qualcuno sa come allegare XmlAdapter personalizzato a oggetti contenuti in una lista eterogenea (come Elenco)? Per esempio - Supponiamo di avere una classe contenitore con una lista di oggetti Altro:JAXB: XmlAdapter per elenco <Object> elementi

@XmlRootElement(name = "container") 
public class Container { 
    private List<Object> values = new ArrayList<Object>(); 

    @XmlElement(name = "value") 
    public List<Object> getValues() { 
     return values; 
    } 

    public void setValues(List<Object> values) { 
     this.values = values; 
    } 
} 

Se mettiamo String -s, -s Integer e così via saranno mappati per impostazione predefinita. Ora supponiamo di voler mettere un oggetto personalizzato:

public class MyObject { 
    //some properties go here 
} 

La soluzione più ovvia è quella di scrivere un adattatore personalizzato:

public class MyObjectAdapter extends XmlAdapter<String, MyObject> { 
    //marshalling/unmarshalling 
} 

Ma purtroppo non funziona con il pacchetto a livello @XmlJavaTypeAdapter - Adattatore basta mai chiamato così fallisce il marhalling. E non posso applicarlo a getValues() direttamente perché ci possono essere altri tipi di oggetti. @XmlJavaTypeAdapter funziona solo se ho un campo di tipo MyObject nel contenitore (anche a livello di pacchetto con annotaton):

public class Container { 
    private MyObject myObject; 
} 

Ma questo non è quello che voglio - voglio un elenco di oggetti arbitrari. Sto usando l'implementazione JAXB standard di Sun:

<dependency> 
    <groupId>com.sun.xml.bind</groupId> 
    <artifactId>jaxb-impl</artifactId> 
    <version>2.2.3-1</version> 
</dependency> 

Qualche idea su come eseguire la mappatura?

P.S .: Un piccolo chiarimento: vorrei evitare di annotare MyObject con annotazioni JAXB. Potrebbe trattarsi di una classe di una libreria di terze parti che non è sotto il mio controllo. Quindi qualsiasi modifica dovrebbe essere al di fuori di MyObject.

+0

Un 'ContextResolver' potrebbe essere una buona soluzione qui ... – Mark

risposta

0

Si potrebbe provare a modificare il MyObjectAdapter in modo che si estende XmlAdapter<String, List<Object>>. Così dovrebbe essere simile a questa:

public class MyObjectAdapter extends XmlAdapter<String, List<Object>> { 
    //marshalling/unmarshalling 
} 

Quando anche si aggiunge un'annotazione XmlJavaTypeAdapter alla getter nella classe Container, dovrebbe funzionare.

@XmlRootElement(name = "container") 
public class Container { 
    private ArrayList<Object> values = new ArrayList<Object>(); 

    @XmlElement(name = "value") 
    @XmlJavaTypeAdapter(MyObjectAdapter.class) 
    public ArrayList<Object> getValues() { 
     return values; 
    } 

    public void setValues(ArrayList<Object> values) { 
     this.values = values; 
    } 
}