2012-01-12 22 views
6

Sto refactoring del codice per utilizzare JAXB e la riflessione sul codice di output per il client, al momento utilizza un XMLWriter e crea manualmente i tag ogni volta.È possibile modificare il valore predefinito dell'attributo nillable in JAXB?

Il problema che sto avendo è che a causa dei vincoli sul lato client, ho bisogno di avere elementi vuoti nell'XML per qualsiasi campo nullo nella classe java.

Mentre mi rendo conto che questo problema può essere risolto aggiungendo nillable=true a ciascuna annotazione JAXB XmlElement, questo non è il più pratico, poiché ho molte di quelle annotazioni.

Speravo di trovare un modo per impostare nillable=true come attributo globale (o come valore predefinito). Ciò renderebbe anche più semplice per i futuri colleghi lavorare su di esso, poiché non sarà necessario ricordare che ogni annotazione dovrebbe includere l'attributo nillable.

Non ho trovato molto oltre alla descrizione del comportamento predefinito. Trovo sorprendente che nessun altro abbia pubblicato una domanda simile in passato. Da quello che ho trovato, non mi sembra che ci sia un supporto integrato per rendere configurabile il default. È qualcosa che potrebbe essere risolto con un'implementazione JAXB personalizzata o forse un'implementazione JAXB di terze parti?

risposta

1

Nota: Sono in vantaggio EclipseLink JAXB (MOXy) e un membro del gruppo di esperti JAXB 2 (JSR-222).

ho inserito una richiesta di miglioramento per avere questo comportamento aggiunto EclipseLink JAXB (Moxy):

aggirare

Come un lavoro intorno se tutta la vostra i campi/proprietà stringa mappati sono mappati su elementi XML, quindi il seguente approccio XmlAdapter potrebbe funzionare automaticamente:

NullStringAdapter

Questo XmlAdapter saranno maresciallo istanze di String come un oggetto chiamato AdaptedString. AdaptedString contiene il valore String e un campo mappato all'attributo xsi:nil. Nel XmlAdapter imposteremo il valore di quel campo in base al fatto che il valore String sia nullo.

package forum8841221; 

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

public class NullStringAdapter extends XmlAdapter<NullStringAdapter.AdaptedString, String> { 

    @Override 
    public AdaptedString marshal(String v) throws Exception { 
     AdaptedString adaptedString = new AdaptedString(); 
     if(null == v) { 
      adaptedString.nil = true; 
     } 
     adaptedString.value = v; 
     return adaptedString; 
    } 

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

    public static class AdaptedString { 

     @XmlAttribute(namespace="http://www.w3.org/2001/XMLSchema-instance") 
     public Boolean nil; 

     @XmlValue 
     @XmlJavaTypeAdapter(VoidStringAdapter.class) 
     public String value; 

    } 

    public static class VoidStringAdapter extends XmlAdapter<String, String> { 

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

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

    } 

} 

pacchetto-info

Possiamo registrare che vogliamo che questo XmlAdapter da applicare a tutte le mappati String campi/proprietà su questo pacchetto registrando il XmlAdapter a livello di pacchetto.

@XmlJavaTypeAdapter(value=NullStringAdapter.class, type=String.class) 
@XmlSchema(xmlns={@XmlNs(namespaceURI = "http://www.w3.org/2001/XMLSchema-instance", prefix = "xsi")}) 
package forum8841221; 

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

Root

Di seguito si riporta la classe di dominio ho usato per questo esempio.Esso ha diverse proprietà stringa, uno di loro è annotata con @XmlElement (nillable = true)

package forum8841221; 

import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Root { 

    private String a; 
    private String b; 
    private String c; 
    private String d; 

    public String getA() { 
     return a; 
    } 

    public void setA(String a) { 
     this.a = a; 
    } 

    public String getB() { 
     return b; 
    } 

    public void setB(String b) { 
     this.b = b; 
    } 

    public String getC() { 
     return c; 
    } 

    public void setC(String c) { 
     this.c = c; 
    } 

    @XmlElement(nillable=true) 
    public String getD() { 
     return d; 
    } 

    public void setD(String d) { 
     this.d = d; 
    } 

} 

Demo

package forum8841221; 

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

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Root.class); 

     Root root = new Root(); 
     root.setB("B"); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(root, System.out); 
    } 

} 

uscita

<?xml version="1.0" encoding="UTF-8"?> 
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <a xsi:nil="true"/> 
    <b>B</b> 
    <c xsi:nil="true"/> 
    <d xsi:nil="true"/> 
</root> 
Problemi correlati