JAXB Marshalling avec champs nuls

<!-C'est une requête assez simple, mais je n'ai pas trouvé le moyen de le faire.

j'essaie de configurer un rôle dans JAXB qui dit que chaque fois qu'un champ nul est rencontré, au lieu de l'ignorer dans la sortie, le régler à une valeur vide. Ainsi, pour la classe :

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

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

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

Merci,

Jalpesh.

46
demandé sur Michael Myers 2009-05-13 19:16:39

5 réponses

Merci les gars pour vos réponses.

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

je suis tombé sur la réponse après que quelqu'un dans les forums de Jersey m'a pointé à la section de la documentation 2.2.12.8 Aucune Valeur.

fondamentalement, tout ce que j'avais à faire était d'ajouter ce qui suit à mes champs :

@XmlElement(nillable = true) 

Une Fois I JAXB a ajouté que JAXB afficherait ces champs lors de leur formation en XML comme ceci:

...
<num>5</num>
<date xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
....
38
répondu Jalpesh 2011-11-19 18:27:51

mais, mais, Mais...une chaîne vide n'est pas une représentation lexicale valide pour une date, donc vous ne pouvez pas faire ça. par exemple, si vous avez généré un document XML avec une valeur vide pour un champ date, il ne sera pas validé correctement.

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

4
répondu Chris Jester-Young 2009-05-13 15:28:50

Comme indiqué dans l'autre réponse est invalide car elle n'est pas une date valide. J'ai eu un problème similaire où je voulais traiter (même 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 suivante si aucune n'est spécifiée. Vous pouvez par le 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 détecter et de vider la valeur date mais vous ne pouvez pas utiliser null pour le faire.

1
répondu Chris Dail 2009-05-13 16:45:11

dans MOXy u peut spécifier comment le jsonProvider doit faire son travail pour JAXB.

donc en faisant 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 était 8.5 cependant, newMoxyJsonProvider () n'est pas nécessaire, mais alors le fournisseur JAXB est configuré par le serveur. Dans le cas de Glassfish, qui est livré avec MOXy, j'ai été témoin des mêmes problèmes avec des valeurs null. N'a pas encore vérifié, mais devinez la réponse est dans la configuration de JAXB au niveau du serveur d'application si possible à tous.

1
répondu Jan Serneels 2013-03-05 11:11:22

essaye ceci:

marshal.setListener(new MarshallerListener());

public class MarshallerListener extends Marshaller.Listener {

    public static final String BLANK_CHAR = "";

    @Override
    public void beforeMarshal(Object source) {
        super.beforeMarshal(source);
        Field[] fields = source.getClass().getDeclaredFields();
        for (Field f : fields) {
            f.setAccessible(true);
            try {
                if (f.getType() == String.class && f.get(source) == null) {
                    f.set(source, BLANK_CHAR);
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
}
0
répondu xudd 2018-08-30 07:18:22