Pourquoi et quand JAXBElement est nécessaire dans JAXB?
J'apprends juste JAXB (Java Architecture for XML Binding). La lecture par le biais de quelques sources , le doute est venu dans mon esprit à l'égard de JAXBElement
.
Oracle docs disent:
When XML element information can not be inferred by the derived Java representation of the XML content, a JAXBElement object is provided. This object has methods for getting and setting the object name and object value.
Lien ici
signifie que JAXBElement
doit être utilisée lorsqu'il n'est pas une correspondance directe entre le Schéma défini le type de données et Java de type de données?
De plus, Dans un des exemples de code répertorié sous. que j'ai suivi de ici :
ObjectFactory factory = new ObjectFactory();
UserT user = factory.createUserT();
user.setUserName("Sanaulla");
ItemT item = factory.createItemT();
item.setItemName("Seagate External HDD");
item.setPurchasedOn("August 24, 2010");
item.setAmount(new BigDecimal("6776.5"));
ItemListT itemList = factory.createItemListT();
itemList.getItem().add(item);
ExpenseT expense = factory.createExpenseT();//we get expense object here
expense.setUser(user);
expense.setItems(itemList);
JAXBContext context = JAXBContext.newInstance("generated");
JAXBElement<ExpenseT> element = factory.createExpenseReport(expense);//why is this required
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty("jaxb.formatted.output",Boolean.TRUE);
marshaller.marshal(element,System.out);
À l'aide de ExpenseT expense = factory.createExpenseT();
nous sommes en mesure d'obtenir ExpenseT
objet.
De nouveau dans le code, si nous le voyons ,nous créons
JAXBElement<ExpenseT> element = factory.createExpenseReport(expense);
qui, selon cette source est un wrapper pour expense
objet.
D'autre part, nous ne créons pas des wrappers pour les objets récupérés en utilisant l' UserT user = factory.createUserT();
Donc mes questions sont :
- Quel est le besoin de
JAXBElement
wrapper autour deexpense
? - quand utiliser
JAXBElement
?
Vous devez vous connecter pour publier un commentaire.
Il y a quelques cas d'utilisation où un
JAXBElement
est nécessaire:nillable="true"
etminOccurs="0"
. Dans ce cas, ce que nenull
sur le champ mappé/biens? Lorsque la propriété estJAXBElement
une valeur nulle signifie que l'élément n'est pas présent et unJAXBElement
emballage null signifie un élément XML avecxsi:nil="true"
.foo
oubar
éléments peuvent se produire, et ils sont du même type. Ici unJAXBElement
est nécessaire parce que tout simplement la rencontre d'unString
valeur n'est pas suffisant pour indiquer l'élément doit être muselé.xsi:nil
est rencontré dans le document qui contient des attributs. Dans cet exemple, l'objet correspondant à cet élément peut encore être unmarshalled pour contenir les valeurs d'attribut, mais JAXBElement peut encore indiquer que l'élément est null.expense
objet, il génère le même code XML de sortie.J'ai donc été un peu confus, pourquoiJAXBElement
wrapper est généré et muselé.Expense
classe ressembler? Avez-vous modifier après qu'il a été généré à partir du schéma XML?expense
objet, il jette `javax.xml.bind.MarshalException exception :impossible de maréchal de type "XSDtoXMLtoObjects.ExpenseT" comme un élément parce qu'il manque un @XmlRootElement annotation. Désolé le dernier commentaire a été mal..JAXBElement est utilisé pour conserver le nom de l'élément/l'espace de noms dans les cas d'utilisation où suffisamment d'information n'est pas présente dans le modèle objet. Il est souvent utilisé avec des groupes de substitution.
Sans JAXB metada le résultat sera enveloppé dans un JAXBElement.
Vous pouvez élimine niveau de la racine JAXBElement en utilisant le @XmlRootElement annotation.
Si vous utilisez les fichiers xsd à partir d'une source externe et pas de XmlRootElement annotation est disponible sur les classes générées, à l'aide de JAXBElement au cours de l'ordonnancement des processus peut être vraiment utile puisque vous pouvez unmarshal le xml à un objet à l'aide de la JAXBElement wrapper. Vous verrez que la spécification de la classe elle-même ne fonctionne pas dans ce cas...
Cela fonctionne:
Cela permettra de jeter un JAXBException: