2009-05-13 12 views
46

Ceci est une requête assez simple, mais je n'ai pas trouvé un moyen de le faire. J'essaye fondamentalement de mettre en place un rôle dans JAXB qui dit que chaque fois qu'un champ nul est rencontré, au lieu de l'ignorer dans la sortie, mettez-le à une valeur vide. Donc, pour la classe:JAXB Marshalling avec des champs nuls

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

Lorsque cela a été dans le fichier marshalé XML si le champ de date est nulle, ma sortie n'a pas cet élément en elle. Ce que je veux faire est d'inclure tous les champs dans la sortie; et s'ils sont nuls, remplacez-les par - disons un blanc. Ainsi, la sortie doit être:

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

Merci,

Jalpesh.

+1

Bonne question et réponse! J'ai rencontré le même problème et cela m'a beaucoup aidé. –

Répondre

4

Mais mais ... une chaîne vide n'est pas une représentation lexicale valide pour une date, donc vous ne pouvez pas le faire. c'est-à-dire que si vous avez généré un document XML avec une valeur vide pour un champ de date, il ne sera pas validé correctement.

En d'autres termes, si votre élément date a une minOccurs de 1 ou plus et non nillable, alors vous devez absolument avoir (1 ou plus), les dates qui ne peuvent pas être nuls (ou blancs, ou d'autres non-valeurs).

+0

J'avais l'habitude d'avoir le premier paragraphe de cette réponse sous forme de commentaire (merci à la charmante personne qui l'a surclassé!), Mais j'ai pensé que ce serait plus utile comme réponse, maintenant que je l'ai développé un peu. :-) –

+1

D'accord, mais je ne valide pas le XML, et il n'a pas de schéma. La présence de tous les champs permettra au consommateur final de comprendre plus facilement ce que ce xml signifie. Avant de commencer à me réprimander pour ne pas avoir de schéma xml :) J'utilise ceci depuis un autre framework (Jersey) qui consomme mes objets de données et crache XML/Json en utilisant JAXB. Donc, le seul contrôle que j'ai est sur mes objets de données. En outre, je peux voir une raison de soutenir les valeurs nulles. Pensez à un cas d'utilisation où je veux générer un fichier CSV hors de mon objet de données. Je pourrais utiliser marshal.marshal (elem, myContentHandler). – Jalpesh

+0

Le contentHandler générerait alors le fichier CSV avec le bon format, ce qui ne peut être fait que si aucun de mes champs de données n'est ignoré. – Jalpesh

1

Comme indiqué dans l'autre réponse est invalide car ce n'est pas une date valide. J'ai eu un problème similaire où je voulais gérer (même chose que) spécialement. Puisque vous ne pouvez pas utiliser null, vous pouvez utiliser le mécanisme de valeur par défaut dans JAXB. La valeur par défaut sera la valeur si aucun n'est spécifié. Vous pouvez par code détecter cette date spéciale et gérer ce cas d'exception.

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

Il est donc possible de la valeur de la date détectée et vide, mais vous ne pouvez pas utiliser null pour le faire.

38

Merci les gars pour vos réponses.

Chris Dail - J'ai essayé votre approche, et elle n'a pas vraiment fait ce que je voulais. JAXB ignorait toujours mes valeurs nulles, malgré la définition d'une valeur par défaut pour mes champs.

J'ai trébuché sur la réponse après que quelqu'un dans les forums de Jersey m'a indiqué la section de documentation 2.2.12.8 No Value.

En fait, tout ce que je devais faire était d'ajouter ce qui suit à mes champs:

@XmlElement(nillable = true) 

Une fois que j'ajouté que, JAXB se présenteraient ces champs lorsque les marshalling XML comme ceci:

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

Grande question et réponse - J'ai posté une question de suivi ici sur la façon de simplifier la syntaxe nulle: http://stackoverflow.com/questions/8198945/how-to-set-non-namespaced-nil-and- type de données-attributs-dans-jaxb –

1

Dans MOXy, vous pouvez spécifier comment jsonProvider doit faire son travail pour JAXB.

Donc lorsque vous faites JAX-RS, ajoutez le code suivant dans votre classe dérivée de l'application

J'ai utilisé ce code sur Tomcat 7 avec de bons résultats. (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; 
    } 

Sur Glassfish 3.1.2 et WAS 8.Cependant, newMoxyJsonProvider() n'est pas nécessaire, mais le fournisseur JAXB est configuré par le serveur. Dans le cas de Glassfish, qui vient avec MOXy, j'ai été témoin des mêmes problèmes avec des valeurs nulles. N'a pas encore vérifié, mais suppose que la réponse est dans la configuration de JAXB au niveau du serveur d'application si possible du tout.