Domanda

Cercando di superare un'eccezione calco qui:

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

genera questa eccezione:

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

Non capisco questo - come la classe è stata generata dallo strumento xjc.bat - e le classi ha generato non ho cambiato a tutti - quindi non ci dovrebbero essere problemi di fusione qui - l'unmarshaller in realtà dovrebbe essere dando me indietro di una classe che può essere gettato a FooClass.

Tutte le idee su quello che sto facendo di sbagliato?

È stato utile?

Soluzione

Lo FooClass avere l'annotazione XmlRootElement? In caso contrario, provare:

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

che si basa sul Unofficial JAXB Guida .

Altri suggerimenti

Usa JAXBIntrospector sul JAXBElement per ottenere lo schemaObject come >>

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

Fare riferimento: quando fa JAXB unmarshaller.unmarshal restituisce un JAXBElement o un MySchemaObject?

Ho incontrato lo stesso problema di oggi, visto le risposte qui, fatto qualche ricerca e sembra a me che la soluzione più generica è quella di utilizzare JAXBIntrospector . Quindi -

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

dovrebbe essere scritto come

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

O, meglio ancora, per renderlo più generico -

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

Per una spiegazione più completa lettura questo articolo . Si scopre che il vostro XSD deve essere impostato correttamente, cioè ci deve essere qualche elemento radice che comprende tutti gli altri elementi.

  

XJC non provare a mettere l'annotazione @XmlRootElement su una classe che generiamo da un tipo complesso. L'esatta condizione è un po 'brutto, ma l'idea di base è che se siamo in grado di garantire in modo statico che un tipo complesso non sarà utilizzato da più nomi dei tag diversi, abbiamo messo @XmlRootElement.

mi piacerebbe guardare il file XML e assicurarsi che è più o meno quello che ci si aspetta di vedere.

Mi piacerebbe anche cambiare temporaneamente il codice per:

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

se il primo failes poi il cast di classe sta accadendo all'interno del metodo unmarshalling, se ha successo, allora si può vedere la classe reale che si stanno ottenendo indietro e poi capire perché non è quello che ci si aspetta che sia.

Abbiamo trascorso troppe ore giocherellare con la classe JAXB fabbrica per soddisfare l'unmarshaller. Abbiamo imparato che utilizzando l'unmarshaller senza di chiamare la fabbrica oggetto JAXB-generated funziona bene. Spero che il codice di esempio riscatta la frustrazione di qualcuno:

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);
    }

Sulla base dei anteprime risposte da colleghi, solo nel caso in cui nessuno è ancora alla ricerca di una risposta.

ho avuto il problema di avere l'elemento principale del mio progetto è stato definito come:

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

E quindi mi è stato sempre un eccezione espressi in:

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
    }

Quello che ho fatto è stato quello di cambiare la prima linea del blocco try a:

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

che ha risolto il problema per me.

Sei assolutamente sicuro FooClass è l'elemento principale della sorgente di input XML che avete passato esso? Unmarshall restituirà un oggetto dell'elemento radice creato da xjc.

A volte si ha una definizione XSD con più elementi radice diversi (ad esempio XSD definiti in WSDL) e in tal caso le classi generate manca @XmlRootElement. Così come mbrauh utente già scritto si deve ottenere il valore di JAXBElement. Nel mio caso ho usato:

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

Quindi, utilizzando farmaci generici si può facilmente evitare il doppio tipo colata.

Specifica @XmlRootElement (name = "specifyName", namespace = "namespace") per trasformare oggetti.

Ho anche incontrato il "Javax.xml.bind.JAXBElement non può essere gettato a" errori e ho trovato questa soluzione molto semplice:

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

Dal momento che, a quanto pare, viene restituito un oggetto di tipo JAXBElement, è necessario typecast il suo valore, invece.

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

Prova questo:

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

Nel mio caso, ho l'errore quando si tenta di inviare una petizione di sapone dall'applicazione SoapUI. Ho bisogno di impostare la proprietà 'spazi bianchi Striscia' su true per ignorare questo errore.

Quando il debug del contenuto ricevuto, è una lista con il contenuto successivo:

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

La speranza di aiuto a qualcuno.

Se si ha accesso ed è possibile modificare il XSD. Per me, questo problema aggiunge quando ho generare il XSD da XML con IDEA.

Con questo xml:

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

IDEA generare un XSD così e JAXB non genererà un elemento root:

<?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>

MA, se si modifica il XSD in questo modo (modificare il vostro elemento principale "schema", al fine di ottenere il xs: complexType all'interno dei xs tag: elemento):

<?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 genererà l'elemento principale!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top