2009-05-13 15 views
46

Questa è una richiesta piuttosto semplice, ma io proprio non ha trovato un modo per farlo.JAXB Marshalling con campi nulli

praticamente sto cercando di creare un ruolo nel JAXB che dice che ogni volta che viene rilevato un campo nullo, invece di ignorarlo nell'output, impostata a un valore vuoto. Così, per la classe:

@XMLRootElement 
Class Foo { 
    Integer num; 
    Date date; 
…. 
} 

Quando questo è stato schierato nel file XML, se il campo della data è nullo, la mia uscita non ha quell'elemento in esso. Quello che voglio fare è includere tutti i campi nell'output; e se sono nulli, sostituirli con - diciamo uno spazio vuoto. Così l'uscita dovrebbe essere:

<foo> 
    <num>123</num> 
    <date></date> 
</foo> 

Grazie,

Jalpesh.

+1

Grande domanda e risposta! Ho incontrato lo stesso problema, ed è stato di grande aiuto. –

risposta

4

Ma, ma, ma ... una stringa vuota non è una rappresentazione lessicale valida per una data, quindi non si può farlo. Ad esempio, se hai generato un documento XML con un valore vuoto per un campo data, non verrà validato correttamente.

In altre parole, se il vostro elemento date ha un minOccurs di 1 o più e non nillable, allora è assolutamente necessario disporre (1 o più) le date, che non può essere nulla (o spazi vuoti, o altri valori non).

+0

Avevo il primo paragrafo di questa risposta come commento (grazie alla persona adorabile che lo ha svalutato!), Ma ho pensato che sarebbe stato più utile come risposta, ora che mi sono espanso un po '. :-) –

+1

Concordato, ma non sto convalidando l'xml e non ha uno schema. Avere tutti i campi presenti renderà più facile per il consumatore finale capire cosa significhi questo xml. Prima di iniziare a rimproverarmi per non avere uno schema xml :) Sto usando questo da un altro framework (Jersey) che consuma i miei oggetti dati e sputa XML/Json usando JAXB. Quindi l'unico controllo che ho è sui miei oggetti dati. Inoltre posso vedere un motivo per supportare valori nulli. Pensa a un caso d'uso in cui voglio generare un file CSV dal mio oggetto dati. Potrei usare marshal.marshal (elem, myContentHandler). – Jalpesh

+0

Il contentHandler genera quindi il file CSV con il formato corretto, che può essere eseguito solo se nessuno dei miei campi dati viene ignorato. – Jalpesh

1

Come indicato nel altra risposta non è valida in quanto non è una data valida. Ho avuto un problema simile in cui volevo gestire (lo stesso di) appositamente. Poiché non è possibile utilizzare null, è possibile utilizzare il meccanismo del valore predefinito in JAXB. Il seguente valore predefinito se nessuno è specificato. È possibile tramite il codice rilevare questa data speciale e gestire questa eccezione.

@XmlElement(defaultValue="1970-01-01T00:00:00.0-00:00") 

Quindi è possibile rilevare e svuotare il valore della data ma non è possibile utilizzare null per farlo. ragazzi

38

Grazie per le vostre risposte.

Chris Dail - ho cercato il suo approccio, e non ha davvero fare quello che volevo. JAXB ignorava ancora i miei valori nulli, nonostante la definizione di un valore predefinito per i miei campi.

ho inciampo nella risposta dopo qualcuno nei forum Jersey mi ha segnalato sezione relativa alla documentazione 2.2.12.8 No Value.

In sostanza, tutto quello che dovevo fare era di aggiungere la seguente ai miei campi:

@XmlElement(nillable = true) 

Una volta ho aggiunto che, JAXB si presentava quei campi quando li marshalling in XML in questo modo:

... 
<num>5</num> 
<date xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/> 
.... 
+0

Grande domanda e risposta - Ho postato una domanda di follow-up qui su come semplificare la sintassi nil: http://stackoverflow.com/questions/8198945/how-to-set-non-namespaced-nil-and- tipo di dati-attributi-a-JAXB –

1

In MOXy è possibile specificare in che modo jsonProvider deve eseguire il proprio lavoro per JAXB.

Così quando si fa JAX-RS, aggiungere seguente codice nella classe derivata da Application

Ho usato questo codice su Tomcat 7 con buoni risultati. (eclipselink 2.4.1)

@ApplicationPath("/rest") 
public class RestApplication extends Application 
{ 

    ... 

public Set< Object> getSingletons() 
    { 

    HashSet<Object> set = new HashSet<Object>(1); 
    set.add(newMoxyJsonProvider()); 

    return set; 
    } 


public static MOXyJsonProvider newMoxyJsonProvider() 
    { 

    MOXyJsonProvider result = new MOXyJsonProvider(); 

    //result.setAttributePrefix("@"); 
    result.setFormattedOutput(false); 
    result.setIncludeRoot(false); 
    result.setMarshalEmptyCollections(true); 
    //result.setValueWrapper("$"); 

    return result; 
    } 

Su Glassfish 3.1.2 e WAS 8.5 tuttavia, newMoxyJsonProvider() non è necessario, ma il server JAXB viene configurato dal server. Nel caso di Glassfish, che viene fornito con MOXy, ho riscontrato gli stessi problemi con valori nulli. Non ho ancora controllato, ma suppongo che la risposta sia nella configurazione di JAXB a livello del server delle applicazioni, se possibile.

Problemi correlati