Pregunta

El intentar conseguir más allá de una excepción de difusión clase aquí:

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

lanza esta excepción:

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

No entiendo esto - como la clase fue generada por la herramienta xjc.bat - y las clases que generó no he cambiado en absoluto - por lo que no debería haber ningún problema de fundición aquí - la unmarshaller debe realmente me estará dando volver a una clase que pueda emitir a FooClass.

Alguna idea de lo que estoy haciendo mal?

¿Fue útil?

Solución

¿Tiene FooClass tener la anotación XmlRootElement? Si no, pruebe:

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

que se basa en la Guía no oficial JAXB .

Otros consejos

Uso JAXBIntrospector en el JAXBElement para obtener el schemaObject como >>

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

Consulte: cuando hace JAXB unmarshaller.unmarshal devuelve un JAXBElement o una MySchemaObject?

Me encontré con el mismo problema hoy en día, vi las respuestas aquí, hice algunas investigaciones y me parece que la solución más genérica es utilizar JAXBIntrospector . Por lo tanto -

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

debería ser escrita como

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

O mejor aún, para que sea más genérico -

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

Para una explicación más detallada lea este artículo . Resulta que su XSD debe estar correctamente configurado, es decir, debe haber algún elemento raíz que abarca todos los demás elementos.

  

XJC no tratar de poner la anotación @XmlRootElement en una clase que se genera a partir de un tipo complejo. La condición exacta es algo feo, pero la idea básica es que si podemos garantizar de forma estática que un tipo complejo no va a ser utilizado por varios nombres diferentes de etiquetas, ponemos @XmlRootElement.

me vería en el archivo XML y asegurarse de que es más o menos lo que espera ver.

También me gustaría cambiar temporalmente el código para:

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

Si el primero failes entonces el elenco de clase que está sucediendo dentro del método unmarshal, si tiene éxito, entonces usted puede ver la clase real de que está recibiendo la espalda y luego averiguar por qué no es lo que usted espera que sea.

Nos pasamos demasiadas horas jugando con la clase de fábrica JAXB para satisfacer la unmarshaller. Hemos aprendido que el uso de la unmarshaller sin llamando a la factoría de objetos generados por JAXB funciona bien. Espero que el código de ejemplo rescata la frustración de alguien:

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

Sobre la base de las vistas previas de las respuestas de sus colegas, por si alguien todavía está buscando una respuesta.

tuve la cuestión de tener el elemento raíz de mi esquema se define como:

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

Y, por tanto, que era conseguir una excepción de difusión en:

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
    }

Lo que hice fue cambiar la primera línea del bloque try a:

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

Esto resuelve el problema para mí.

¿Estás absolutamente seguro de FooClass es el elemento raíz de la fuente de entrada XML que le es? Resolver referencia volverá un objeto del elemento raíz creado por xjc.

A veces hay una definición XSD con múltiples elementos raíz diferentes (por ejemplo XSD definidos en WSDL) y en ese caso las clases generadas se echa en falta @XmlRootElement. Así como mbrauh de usuario que ya escribieron usted tiene que obtener el valor de JAXBElement. En mi caso he utilizado:

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

Así que el uso de los genéricos se puede fácilmente evitar la doble conversión de tipos.

Especificar @XmlRootElement (name = "specifyName", espacio de nombres = "espacio de nombres") para la transformación de objeto.

También encontré con el "Javax.xml.bind.JAXBElement no se puede convertir a un" error y encontré esta solución muy simple:

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

Dado que, al parecer, se devuelve un objeto de tipo JAXBElement, es necesario encasillado su valor en su lugar.

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

Prueba esto:

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

En mi caso, me sale el error al intentar enviar una petición de jabón de la aplicación SOAPUI. Necesito establecer la propiedad '' espacios en blanco de la tira en true para omitir este error.

Cuando depurar el contenido recibido, es una lista con el siguiente contenido:

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

La esperanza ayuda a alguien.

Si usted tiene acceso y puede modificar el XSD. Para mí, esta cuestión anexa al genero el XSD de XML con IDEA.

Con este XML:

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

IDEA generar un XSD así y JAXB no generará un elemento raíz:

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

Pero, si modifica el XSD de esta manera (modificar su elemento raíz "esquema" con el fin de obtener la xs: complexType el interior de los xs etiqueta: 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 generará el elemento raíz

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top