web-dev-qa-db-fra.com

Java JaxB - Object to XML String to Object

J'ai un problème avec JaxB dans Netbeans 7.1.2.

J'ai généré automatiquement mes classes à partir d'un schéma à l'aide de JaxB (New JaxB Binding). Je crée l'objet qui sera sérialisé en une chaîne XML à l'aide du Marshaller, puis de nouveau vers une nouvelle instance d'objet à partir de la chaîne XML. Cependant, j'obtiens l'exception suivante:

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.somewhere.com/some/path", local:"MyQueryComplexTypeQuery"). Expected elements are (none)

Le marshaling/sérialisation en chaîne XML fonctionne très bien. C'est quand il n'est pas manipulé/désérialisé qui cause le problème.

J'utilise le code suivant pour construire l'objet et le rassembler en une chaîne XML:

// build the object
ObjectFactory of = new ObjectFactory();

MyQueryComplexType oaaqc = of.createMyQueryComplexType();
oaaqc.setField1("edit");
oaaqc.setField2("net");
oaaqc.setField3("24");

JAXBElement<MyQueryComplexType> createMyQueryComplexType = of.createMyQueryComplexTypeQuery(oaaqc);

// serialise to xml
StringWriter writer = new StringWriter();
JAXBContext context = JAXBContext.newInstance(MyQueryComplexType.class);            
Marshaller m = context.createMarshaller();
m.marshal(createMyQueryComplexType, writer);

// output string to console
String theXML = writer.toString();
System.out.println(theXML);

Cela produit le XML suivant (formaté) dans la console:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MyQueryComplexTypeQuery xmlns="http://www.somewhere.com/some/path">
    <Field1>edit</Field1>
    <Field2>net</Field2>
    <Field3>24</Field3>
</MyQueryComplexTypeQuery>

Maintenant, je viens de désérialiser/démarsaler la chaîne vers une nouvelle instance MyQueryComplexType avec le code suivant:

Unmarshaller u = context.createUnmarshaller();
MyQueryComplexTypeQuery o = (MyQueryComplexType) u.unmarshal(new StringReader(theXML));

Dans le package-info.Java généré automatiquement, il contient le contenu suivant:

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.somewhere.com/some/path", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package MyProject.SomeNamespace.MyQuery;

Je pensais que le processus simple d'objet -> chaîne -> objet fonctionnerait. C'est la première fois que j'utilise JaxB (alors soyez doux). J'ai vu d'autres articles mentionner les espaces de noms, et tout me semble correct. J'ai généré automatiquement les classes à partir du schéma, construit l'objet, rassemblé en chaîne xml. Je pensais que simplement inverser le processus pour unmarshal serait similaire.

L'exception réelle est levée en ligne:

MyQueryComplexTypeQuery o = (MyQueryComplexType) u.unmarshal(new StringReader(theXML));

Je pensais que je faisais unmarshalling de chaîne à objet serait simple. Je ne sais pas si je fais quelque chose de mal ou si je manque quelque chose. J'espère que vous pouvez faire la lumière ou ouvrir les yeux.

J'ai réduit le code pour simplifier ce qui se trouve dans mon application et qui cause l'erreur. Les espaces de noms ont été modifiés pour protéger l'identité des objets sur le Web.

Des pensées?

Merci

Andez

15
Andez

Création du JAXBContext

Pour les modèles JAXB générés à partir d'un schéma XML, vous pouvez créer le JAXBContext sur le nom du package plutôt que sur une classe particulière:

JAXBContext context = JAXBContext.newInstance("your.package.name");

Ne pas:

JAXBContext context = JAXBContext.newInstance(MyQueryComplexType.class);  

Cela garantira que la classe ObjectFactory qui contient le @XmlElementDecl les annotations sont traitées correctement, ce qui manque dans votre cas d'utilisation.

Opération anti-maréchal

Notez que pendant votre opération de marshal, vous deviez envelopper votre instance de MyQueryComplexType dans un JAXBElement? En effet, MyQueryComplexType n'a pas été annoté avec @XmlRootElement et les informations sur l'élément racine devaient provenir de JAXBElement. Cela signifie que lorsque vous effectuez l'opération sans maréchal, vous obtenez également un JAXBElement.

JAXBElement<MyQueryComplexTypeQuery> o = (JAXBElement<MyQueryComplexType>) u.unmarshal(new StringReader(theXML));

Ne pas:

MyQueryComplexTypeQuery o = (MyQueryComplexType) u.unmarshal(new StringReader(theXML));

Pour plus d'informations

18
bdoughan