JAXB élément qui est à la fois facultatif et nillable
J'ai re-formaté la question, nous l'espérons, pour rendre ma pensée plus claire.
Architecture
Je suis en train d'écrire certains services web, que je vais publier moi-même à l'aide de JAX-WS. Le processus que nous avons utilisé pendant un certain temps est d'abord écrire un schéma qui définit seulement les objets request et response. Ce est envoyé au client à approuver la structure des messages xml. Je ne veux pas écrire tout le wsdl moi-même que c'est plus compliqué que le schéma de base.
Ensuite, j'utilise le JAXB commande xjc pour générer des classes en fonction de la demande et de la réponse des types dans mon schéma. J'ai ensuite utiliser ces classes que les paramètres et les types de retour sur un JAX-WS annoté point de terminaison de la classe.
Cela me donne un service web, je peux appeler. Cela me donne plus de contrôle sur le xml envoyés et retournés, mais aussi automatise la répétition nécessaire à l'écriture de l'pleine wsdl.
Problème
Dans le schéma que j'ai un élément comme ceci:
<xs:element name="myElement" type="xs:string" nillable="true" minOccurs="0" />
Je tiens donc à distinguer entre l'utilisateur réglage de la valeur null ou vide. La classe générée puis a cet attribut.
@XmlElementRef(name = "myElement", namespace = "/mynamespace", type = JAXBElement.class)
protected JAXBElement<String> myElement;
L'effet de ceci est que l'élément devient ni nillable ou facultatif. Le schéma que JAX-WS écrit dans le cadre de l'wsdl a défini l'élément obligatoire et pas nillable et si je désactive la validation du schéma, je ne peux pas passer à néant par le biais de mon objet.
Choses essayé
Si je change exigée et nillable puis-je obtenir le code généré.
@XmlElement(required = true, nillable = true)
protected String myElement;
Si je l'ai changer d'option et de ne pas nillable puis-je obtenir le code généré.
protected String myElement
De sorte que vous pouvez avoir deux ou mais pas les deux, il semble que si vous utilisez JAXB. Complètement décevant!
J'ai aussi essayé de modifier manuellement la classe générée à ressembler à cela.
@XmlElementRef(name = "myElement", namespace = "/mynamespace", type = JAXBElement.class, required=false)
protected JAXBElement<String> myElement;
Cela fait maintenant de l'élément optionnel, mais je n'arrive toujours pas à néant. Cette opération aboutit à un JAXBElement avec une valeur de chaîne vide. C'est uniquement si vous activez la validation du schéma de comme la résultante de JAX-WS wsdl/schéma ne pas définir l'élément nillable, donc ce n'est pas une demande valide.
Résumé
C'est ma conviction que c'est un bug avec JAXB. @XmlElementRef annotation a un attribut pour définir qu'il n'est pas nécessaire, mais il n'y a pas d'attribut pour définir le champ comme nullable.
L' @XmlElement annotation a des attributs à la fois nécessaire et nullable mais ces juste le résultat dans un objet null si il n'y aurait aucun moyen de distinguer entre un élément non inclus dans le fichier xml ou un élément qui a été inclus, mais la valeur null. C'est pourquoi vous devez utiliser @XmlElementRef avec JAXBElement.
Je pense que le bug comprend deux questions. D'abord le xjc commande doit générer l'élément avec required=false. Deuxièmement, il doit être un attribut sur @XmlElementRef pour définir si l'élément est nullable et cela devrait être réglé trop.
Personne ne sait d'une solution/solution de contournement? J'ai essayé de googler, mais seulement constaté que les gens posent la même question sans réponse. Cela signifie généralement qu'il n'est pas possible... TIA.
Supplémentaires
Je suis l'aide de jaxb 2.2.6 et le plugin maven est jaxb2-maven-plugin 1.5.
OriginalL'auteur Ben Thurley | 2013-10-29
Vous devez vous connecter pour publier un commentaire.
TL;DR
Pour
Une absence de nœud dans le document correspondent à ce champ est null. Un élément XML présents dans le document avec
xsi:nil="true"
correspondra à la valeur d'une instance deJAXBElement
avec une valeur denull
.Vous pouvez également fournir un schéma XML au lieu d'avoir JAXB générer à l'aide de la
location
de propriété sur l'ensemble des@XmlSchema
annotation.Maréchal/Unmarshal
Java Modèle
Racine
C'est un objet avec les deux champs qui peuvent représenter facultatif et nillable de données.
ObjectFactory
Le Code De Démonstration
Démo
La démo de code ci-dessous va étudier les différences dans les valeurs de
foo
etbar
. Vous pouvez utiliser leJAXBIntrospector
classe pour obtenir la valeur réelle d'une instance deJAXBElement
. Il y a un bug dans EclipseLink JAXB (MOXy) liées à unmarshalling une instance deJAXBElement
emballage une valeur null (voir: http://bugs.eclipse.org/420746).d'entrée.xml/Sortie
Dans le résultat, nous voyons que nous pouvons distinguer entre un élément absent du document et d'un élément avec " xsi:nil="true" et ont encore de la valeur nulle.
Générer un Schéma XML
Le Code De Démonstration
GenerateSchema
Ci-dessous quelques JAXB code qui permettra de générer un Schéma XML à partir du modèle annoté.
Sortie
Ici est celle du Schéma XML. Vous avez raison qu'il n'indique pas que le
foo
etbar
éléments sont nillable.Fournir un Schéma XML
Au lieu d'avoir JAXB tirer un Schéma XML à partir de votre modèle, vous pouvez pointer vers votre existant qui contiennent plus d'information.
paquet-info
C'est fait en spécifiant le
location
de propriété sur l'ensemble des@XmlSchema
annotation.Merci quand même, j'ai été légèrement reformulé l'espoir de le rendre plus clair.
J'ai mis à jour ma réponse à l'espérons, de mieux répondre à vos question.
Je ne peux pas facilement à un schéma. Je suis à l'aide de JAX-WS pour déployer ce qu'un service web afin de JAX-WS est en utilisant les annotations JAXB pour créer un fichier wsdl. Je pourrais écrire le wsdl par la main et le point à cela, mais je ne veux pas le faire.
OriginalL'auteur Blaise Doughan
Comme je vous comprends Ben suivantes XSD:
Devrait se traduire par:
Droit?
Mais pour défaut JAXB mise en œuvre, il n'est pas le cas. Ressemble à un bug dans JAXB. Je n'ai pas trouver dans JAXB outil de suivi d'.
required
attribut a été introduit à@XmlElementRef
dans JAXB 2.2 dans autour de 2009, mais apparemment, personne n'a créé de ce problème.required
attribut ne peut pas être modifié à l'aide de la Liaison de Personnalisations.Dans cette situation, vous pouvez:
@XmlElementRef
annotation. Il n'est pas difficile. Plus d'informations ici.required = false
est généré à l'aide de MOXy JAXB compilateur)Peu importe l'option que vous choisissez s'il vous plaît faire problème dans JAXB issue tracker de sorte que le problème sera résolu.
EDIT:
De montrer que la création de plugin est facile, j'ai créé un. Vous pouvez le trouver dans mon github. N'hésitez pas à utiliser, copier, modifier à volonté. Je ne donne pas de garantie que cela fonctionne à 100%, mais pour les cas simples fonctionne comme un charme.
EDIT2:
Si le schéma généré en fonction des objets java et les annotations JAXB ne correspond pas à votre interface, vous pouvez utiliser
@WebService.wsdlLocation
au point d'origine, de rectification WSDL et XSD fichiers.EDIT3:
C'est bizarre que
nil
est ignoré par JAXB dans votre cas. J'ai couru un test à l'aide de JAXB 2.2.6 et 2.2.7 etnil
est correctement reconnu:Pourriez-vous vérifier si vous avez correctement réglé nul attribut, par exemple:
Si elle est correcte, essayez d'exécuter le test avec votre classe.
Désolé, mais je ne comprends pas qu'est-ce que le réglage de la JAXBElement comme nill. Voulez-vous dire que les messages d'entrée ne sont pas unmarshalled correctement? Btw. J'ai mis à jour ma réponse, de sorte que vous pouvez contourner le problème de la mauvaise schéma XML généré.
Oui, si vous appelez le service web en passant dans l'élément nul, donc il n'est pas reflété dans le résultat de l'JAXBElement. Si vous appelez getValue sur le JAXBElement vous obtenez une chaîne vide. Si vous appelez isNil vous obtenir de faux. Il est également l'échec de la validation par rapport au schéma, donc j'ai dû l'éteindre pour en arriver là. Réglage de l'emplacement wsdl n'est pas vraiment une option, parce que je n'ai qu'un schéma pour définir la demande et les types de réponses. Je veux JAX-WS pour générer le reste du wsdl pour moi. À partir de ce que je peux dire @XmlElementRef ne prend pas en charge tous les deux en option et accepte la valeur null. Il ne dispose que d'un attribut défini comme requis.
Je ne peux pas reproduire le problème avec JAXB unmarshalling
nil
de manière incorrecte. Veuillez jeter un oeil à mon dernier edit.J'ai utilisé votre exemple pour générer du xml et ensuite de les convertir en arrière dans un objet. J'ai eu à jouer avec elle un peu, mais finalement, j'ai été capable de le faire de triage et unmarshalling. Cependant, je continue de se décoller quand il s'agit de la validation du schéma parce que l'élément n'est pas nillable dans le schéma. Je ne sais pas si c'est un problème avec JAX-WS ou JAXB.
OriginalL'auteur Dawid Pytel
Vous pouvez personnaliser la liaison par
Comme documenté dans Personnalisé De Liaison , pour exactement le même cas que vous posez sur.
Je suis à l'aide personnalisée de liaison avec le plugin maven org.jvnet.jaxb2.maven2:maven-jaxb2-plugin
OriginalL'auteur M-Zaiady