studio programacion móviles libros libro desarrollo desarrollar curso aprende aplicaciones java jaxb jaxb2

java - móviles - manual de programacion android pdf



¿Excepción de clase lanzada al intentar desmarcar xml? (14)

¿ FooClass tiene la anotación XmlRootElement ? Si no, prueba:

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

Eso se basa en la Guía no oficial de JAXB .

Intentando superar una excepción de reparto de clase aquí:

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

lanza esta excepción:

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

No entiendo esto, ya que la clase fue generada por la herramienta xjc.bat, y las clases que generó no se han alterado en absoluto, por lo que no debería haber problemas de lanzamiento aquí, el implacable realmente debería devolverme una clase que se puede lanzar a FooClass.

¿Alguna idea sobre lo que estoy haciendo mal?


¿Estás absolutamente seguro de que FooClass es el elemento raíz de la fuente de entrada xml que lo pasaste? Unmarshall devolverá un objeto del elemento raíz creado por xjc.


A veces, tiene una definición XSD con múltiples elementos raíz diferentes (por ejemplo, XSD definido en WSDL) y en ese caso faltan las clases generadas @XmlRootElement. Entonces, como el usuario mbrauh ya escribió, debes obtener el valor de JAXBElement. En mi caso utilicé:

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

Así que con los genéricos se puede evitar fácilmente la fundición de doble tipo


En mi caso, recibo el error al intentar enviar una petición de jabón desde la aplicación SOAPUI. Necesito establecer la propiedad ''strip whitespaces'' en true para omitir este error.

Cuando se depura el contenido recibido, aparece una lista con el siguiente contenido:

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

Espero ayudar a alguien.


Especifique @XmlRootElement (name = "especificName", namespace = "namespace") para transformar el objeto.


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

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

debe escribirse como

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

O mejor aún, para hacerlo más genérico.

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


Miraría el archivo XML y me aseguraría de que sea aproximadamente lo que esperas ver.

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

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

Si la primera falla, entonces el reparto de la clase se realiza dentro del método unmarshal, si tiene éxito, puede ver la clase real que está recuperando y luego averiguar por qué no es lo que espera que sea.


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

XJC intenta poner la anotación @XmlRootElement en una clase que generamos a partir de un tipo complejo. La condición exacta es algo fea, pero la idea básica es que si podemos garantizar estáticamente que no se usará un tipo complejo con varios nombres de etiquetas diferentes, colocamos @XmlRootElement .


Pasamos demasiadas horas moviéndonos con la clase de fábrica de JAXB para satisfacer a los no malvados. Hemos aprendido que el uso de unmarshaller sin llamar a la fábrica de objetos generados por JAXB funciona bien. Espero que el código de muestra redima 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); }


Prueba esto:

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


Si tienes acceso y puedes modificar el XSD. Para mí, este problema se agrega cuando genero el XSD desde XML con IDEA.

Con este xml:

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

IDEA genera 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 (modifique su elemento raíz "esquema" para obtener el xs: complexType dentro de la etiqueta xs: 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!


Sobre la base de las respuestas previas de los colegas, en caso de que alguien todavía esté buscando una respuesta.

Tuve el problema de tener el elemento raíz de mi esquema definido como:

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

Y por lo tanto, estaba recibiendo una excepción de reparto 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());

Eso resolvió el problema para mí.


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

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

Dado que, aparentemente, se devuelve un objeto de tipo JAXBElement, debe tipificar su valor en su lugar.

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