Question

Essayer de franchir une exception class cast ici:

FooClass fooClass = (FooClass ) unmarshaller.unmarshal(inputStream);

jette cette exception:

java.lang.ClassCastException: javax.xml.bind.JAXBElement

Je ne comprends pas - que la classe a été générée par l'outil de xjc.bat - et les classes générés pour la plupart je n'ai pas changé du tout - donc il ne devrait y avoir aucun problème de coulée ici - la unmarshaller devrait vraiment être me donner retour d'une classe qui peut être jeté à FooClass.

Toutes les idées sur ce que je fais mal?

Était-ce utile?

La solution

Est-ce que FooClass a l'annotation XmlRootElement? Sinon, essayez:

Source source = new StreamSource(inputStream);
JAXBElement<FooClass> root = unmarshaller.unmarshal(source, FooClass.class);
FooClass foo = root.getValue();

C'est basé sur le Guide JAXB non officiel .

Autres conseils

Utilisez JAXBIntrospector sur le JAXBElement pour obtenir le schemaObject comme >>

JAXBContext jaxbContext = JAXBContext.newInstance(Class.forName(className));
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Object schemaObject = JAXBIntrospector.getValue(unmarshaller.unmarshal(new ByteArrayInputStream(xmlString.getBytes())));

Reportez-vous: quand est-ce JAXB unmarshaller.unmarshal retourne un JAXBElement ou MySchemaObject

Je suis tombé sur le même problème aujourd'hui, vu les réponses ici, fait quelques recherches et me semble que la solution la plus générique est d'utiliser JAXBIntrospector . Par conséquent -

FooClass fooClass = (FooClass ) unmarshaller.unmarshal(inputStream);

doit être écrit comme

FooClass fooClass = (FooClass) JAXBIntrospector.getValue(unmarshaller.unmarshal(inputStream));

Ou mieux encore, pour le rendre plus générique -

T t = (T) JAXBIntrospector.getValue(unmarshaller.unmarshal(inputStream));

Pour une explication plus complète lu cet article . Il se trouve que votre XSD doit être correctement mis en place, à savoir qu'il doit y avoir un élément racine qui englobe tous les autres éléments.

  

XJC ne cherche à mettre l'annotation @XmlRootElement sur une classe que nous générons à partir d'un type complexe. La condition exacte est un peu laid, mais l'idée de base est que si nous pouvons garantir statiquement qu'un type complexe ne sera pas utilisé par plusieurs noms de balise, nous avons mis @XmlRootElement.

Je regarde le fichier XML et assurez-vous qu'il est à peu près ce que vous attendez à voir.

Je voudrais aussi modifier temporairement le code:

Object o = unmarshaller.unmarshal(inputStream);
System.out.println(o.getClass());

Si la première failes alors le casting de classe qui se passe dans la méthode unmarshal, si elle réussit, alors vous pouvez voir la classe réelle que vous obtenez en arrière et comprendre pourquoi il n'est pas ce que vous attendez qu'il soit.

Nous avons passé trop d'heures tripotant la classe usine de JAXB pour satisfaire la unmarshaller. Nous avons appris que l'utilisation du unmarshaller sans appeler l'usine d'objet généré JAXB fonctionne bien. Espère que le code exemple la frustration de racheter quelqu'un:

System.out.println("Processing generic-type unmarshaller: ");
MessageClass mcObject = unmarshalXml(MessageClass.class, msgQryStreamSource,
    NAMESPACE + "." + "MessageClass");

public static <T> T unmarshalXml(Class<T> clazz, StreamSource queryResults,
    String contextNamespace)
    {
        T resultObject = null;
        try {
            //Create instance of the JAXBContext from the class-name
            JAXBContext jc;
            jc = JAXBContext.newInstance(Class.forName(clazz.getName()));
            Unmarshaller u = jc.createUnmarshaller();
            resultObject = clazz.cast(u.unmarshal(queryResults));
            }
              //Put your own error-handling here.
        catch(JAXBException e)
        {
            e.printStackTrace();
        }
        catch (ClassCastException e)
        {
            e.printStackTrace();
        }
        catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
        return clazz.cast(resultObject);
    }

Sur la base des avant-premières réponses de collègues, juste dans tout le monde est à la recherche de cas toujours une réponse.

J'ai eu la question d'avoir l'élément racine de mon schéma étant défini comme:

<schema>
  <element name="foo" type="bar" />
  <complexType name="bar" />
</schema>

Et donc je devenais une exception à Cast:

try {            
        javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(mobilityConfigType.getClass().getPackage().getName());            
        javax.xml.bind.Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller();
        File f = FileUtil.toFile(this.getPrimaryFile());            
        mobilityConfigType = (MobilityModelConfigType)unmarshaller.unmarshal(FileUtil.toFile(this.getPrimaryFile()));
    } catch (javax.xml.bind.JAXBException ex) {            
        java.util.logging.Logger.getLogger("global").log(java.util.logging.Level.SEVERE, null, ex); //NOI18N
    }

Ce que je faisais était de changer la première ligne du bloc à essayer:

javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(mobilityConfigType.getClass().getName());

Ce résolu le problème pour moi.

Êtes-vous absolument sûr FooClass est l'élément racine de la source d'entrée xml vous a transmis? Unmarshall retourne un objet de l'élément racine créé par xjc.

Parfois, vous avez une définition XSD avec plusieurs différents éléments racine (par exemple XSD définies dans WSDL) et dans ce cas, les classes générées manque @XmlRootElement. Alors que mbrauh utilisateur a déjà écrit que vous devez obtenir la valeur de JAXBElement. Dans mon cas, je:

FooClass request = ((JAXBElement< FooClass >) marshaller.unmarshal(new StreamSource(classPathResource.getInputStream()))).getValue();

Donc, en utilisant les médicaments génériques, vous pouvez facilement éviter la coulée de type double.

Spécifiez @XmlRootElement (name = "specifyName", namespace = "namespace") pour objet la transformation.

J'ai aussi rencontré le « Javax.xml.bind.JAXBElement ne peut pas être jeté à » erreur et a trouvé cette solution très simple:

FooClass fooClass = (FooClass) ((JAXBElement) u.unmarshal(new File("xml/foo.xml")) ).getValue();

Depuis, apparemment, un objet de type JAXBElement est retourné, vous devez typecast sa valeur à la place.

Source: https://forums.oracle.com/thread/1625944

Essayez ceci:

JAXBContext jc = JAXBContext.newInstance(Foo.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
JAXBElement element = (JAXBElement) unmarshaller.unmarshal( new StringReader(xmlString));
Foo foo = (Foo)element;

Dans mon cas, je reçois l'erreur en essayant d'envoyer une pétition de savon de l'application SoapUI. J'ai besoin de définir la propriété « strip » espaces blancs true pour ignorer cette erreur.

Lorsque déboguer le contenu reçu, est une liste avec le contenu suivant:

[0] = "\n"
[1] = JAXBElement
[2] = "\n"

quelqu'un aide Hope.

Si vous avez accès et vous pouvez modifier le XSD. Pour moi, cette question quand je produis ajoute le XSD de XML avec IDEA.

Avec ce xml:

<?xml version="1.0"?>
<schema>
  <element name="foo" type="bar" />
  <complexType name="bar" />
</schema>

IDEA générer un XSD comme ça et JAXB ne génère pas un élément racine:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="schema" type="schemaType"/>
  <xs:complexType name="schemaType">
    <xs:sequence>
      <xs:element type="elementType" name="element"/>
      <xs:element type="complexTypeType" name="complexType"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="elementType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:string" name="name"/>
        <xs:attribute type="xs:string" name="type"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="complexTypeType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:string" name="name"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
</xs:schema>

MAIS, si vous modifiez le XSD de cette manière (modifier votre élément racine « schéma » afin d'obtenir la xs: complexType dans la balise xs: element):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="schema">
    <xs:complexType>
      <xs:sequence>
        <xs:element type="elementType" name="element"/>
        <xs:element type="complexTypeType" name="complexType"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="schemaType">
    <xs:sequence>
      <xs:element type="elementType" name="element"/>
      <xs:element type="complexTypeType" name="complexType"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="elementType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:string" name="name"/>
        <xs:attribute type="xs:string" name="type"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="complexTypeType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:string" name="name"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
</xs:schema>

JAXB va générer l'élément racine!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top