2012-01-04 7 views
7

Ho studiato Blaise Doughan's answer to a question on this subject ma ho un'ulteriore domanda.Quali informazioni sul pacchetto annoto con XmlJavaTypeAdapters?

XmlJavaTypeAdapters consente di elencare un gruppo di annotazioni XmlJavaTypeAdapter, ognuna delle quali regola come un tipo non associabile è mappato a un tipo associabile da JAXB.

È possibile utilizzare questa annotazione a livello di pacchetto. Quando si esegue questa operazione, ogni annotazione XmlJavaTypeAdapter richiede l'attributo type() completamente specificato.

Non sembra esserci il requisito che il pacchetto che viene annotato abbia qualcosa a che fare con il pacchetto dei tipi non associabili da adattare. È conveniente e carino.

Questo, tuttavia, mi porta alla mia domanda successiva: se non c'è alcuna relazione tra il pacchetto annotato e il pacchetto del tipo da adattare, in che modo JAXB rileva annotazioni a livello di pacchetto XmlJavaTypeAdapters? In che modo, in altre parole, sa quali pacchetti consultare per le potenziali annotazioni XmlJavaTypeAdapters? Posso creare un pacchetto a caso, ad esempio, nel file .jar nella directory lib del file .ear contenente una singola, gigantesca classe package-info annotata con tutti gli adattatori per tutti i miei tipi non associabili?

risposta

7

Quando il runtime JAXB carica una classe con annotazione JAXB, cerca uno package-info.java nello stesso pacchetto di quella classe e verifica che cerchi le annotazioni a livello di pacchetto. Quindi, mentre XmlJavaTypeAdapters non deve risiedere nello stesso pacchetto dei tipi "non associabili", lo fa devono risiedere nello stesso pacchetto dei tipi "associabili".

Ad esempio, dire ho una classe JAXB annotato A, nel pacchetto X, che ha una struttura di tipo B in pacchetto Y. Per legare la proprietà B, supponiamo che sia necessario un adattatore di tipo. Tale adattatore può essere specificato nello stesso A oppure può essere specificato nello package-info.java nel pacchetto X. Il pacchetto Y è praticamente arbitrario e non interessa il runtime JAXB.

Spero che abbia senso.

+0

molto utile; Grazie. Il grafico si muove da lì? Cioè, supponiamo di avere un singolo bindable type che nutro per JAXB. Supponiamo inoltre che il suo pacchetto sia annotato con 647 annotazioni 'XmlJavaTypeAdapter', ognuna delle quali specifica un tipo non associabile e un adattatore per quel tipo. Il mio 'JAXBContext' ora sarà in grado di gestire tutti i 647 tipi ora adattati? –

+0

@Laird: Sì, a condizione che (a) tu abbia la RAM per gestirlo, e (b) Tutti i tipi di bindable fossero in quel pacchetto. – skaffman

+0

Interessante. Sembra strano che dovrei riavviare l'intero processo, però. Voglio dire, se posso creare una pila di adattatori semplicemente dando a JAXB un singolo tipo, allora mi auguro che dovrebbe essere possibile migliorare JAXB in modo che neanche quel tipo singolo sia necessario. Come se JAXB guardasse di default per un "root" 'package-info' da qualche parte in modo che il bootstrap iniziale non fosse necessario. Grazie ancora per il vostro aiuto. –

5

Non sembra essere un requisito che il pacchetto che è essendo annotata avere a che fare con il pacchetto delle tipi non associabili essendo atto. È conveniente e carino.

Questo è corretto. Quando @XmlJavaTypeAdapter viene utilizzato a livello di pacchetto, significa applicare questo adattatore a tutte le proprietà del tipo specificato per le classi che risiedono in questo pacchetto. Dimostrerò di seguito con un esempio.

forum8735737.bar.package-info

Per questo pacchetto ci sarà specificare un XmlAdapter che verrà applicato a tutti i campi/proprietà di tipo String all'interno di questo pacchetto.

@XmlJavaTypeAdapters({ 
    @XmlJavaTypeAdapter(value=StringAdapter.class, type=String.class) 
}) 
package forum8735737.bar; 

import javax.xml.bind.annotation.adapters.*; 

forum8735737.bar.StringAdapter

nostro XmlAdapter sarà semplicemente convertire tutte le istanze di String a maiuscolo quando marshalling:

package forum8735737.bar; 

import javax.xml.bind.annotation.adapters.XmlAdapter; 

public class StringAdapter extends XmlAdapter<String, String> { 

    @Override 
    public String unmarshal(String v) throws Exception { 
     return v; 
    } 

    @Override 
    public String marshal(String v) throws Exception { 
     if(null == v) { 
      return v; 
     } 
     return v.toUpperCase(); 
    } 

} 

forum8735737.bar.Bar

Bar rappresenta un POJO in questo pacchetto con una proprietà di digitare String:

package forum8735737.bar; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Bar { 

    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

} 

forum8735737.foo.Foo

Foo rappresenta un oggetto dominio con una proprietà di tipo String che esiste in un pacchetto differente. Il XmlAdapter abbiamo registrato per il pacchetto forum8735737.bar non si applicano a questa classe:

package forum8735737.foo; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Foo { 

    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

} 

Demo

Il codice seguente consente di creare istanze di entrambi Foo e Bar e li maresciallo in XML:

package forum8735737; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 

import forum8735737.bar.Bar; 
import forum8735737.foo.Foo; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Foo.class, Bar.class); 
     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     Foo foo = new Foo(); 
     foo.setName("Foo"); 
     marshaller.marshal(foo, System.out); 

     Bar bar = new Bar(); 
     bar.setName("Bar"); 
     marshaller.marshal(bar, System.out); 
    } 

} 

Uscita

notare come il valore dell'elemento name entro bar è stato convertito in lettere maiuscole:

<?xml version="1.0" encoding="UTF-8"?> 
<foo> 
    <name>Foo</name> 
</foo> 
<?xml version="1.0" encoding="UTF-8"?> 
<bar> 
    <name>BAR</name> 
</bar> 
Problemi correlati