JAXB unmarshall con espacios de nombres y prefijo

Estoy usando JAXB para analizar elementos xml de la respuesta SOAP. Definí las clases POJO para los elementos xml. He probado las clases pojo sin espacio de nombres y el prefijo funciona bien. Aunque cuando estoy tratando de analizar con espacios de nombres y prefijo frente a la siguiente excepción.Requisito es analizar la entrada del objeto SOAPMessage

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://schemas.xmlsoap.org/soap/envelope/", local:"Envelope"). Expected elements are

Intenté solucionarlo creando @XMLSchema para el paquete en package-info.java y localicé este archivo en la carpeta del paquete. ¿Puede alguien guiarme para seguir adelante?

Remitió estas publicaciones pero no me ayudó.

EDITADO: XMLSchema

 @javax.xml.bind.annotation.XmlSchema ( xmlns = { @javax.xml.bind.annotation.XmlNs(prefix = "env", namespaceURI="http://schemas.xmlsoap.org/soap/envelope/"), @javax.xml.bind.annotation.XmlNs(prefix="ns3", namespaceURI="http://www.xxxx.com/ncp/oomr/dto/") } ) package com.one.two; 

Gracias por adelantado

Esto se puede hacer sin modificar el código JAXB generado utilizando la clase estándar SOAPMessage. Escribí sobre esto aquí y aquí

Es un poco complicado, pero funciona correctamente.

Marshalling

 Farm farm = new Farm(); farm.getHorse().add(new Horse()); farm.getHorse().get(0).setName("glue factory"); farm.getHorse().get(0).setHeight(BigInteger.valueOf(123)); Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); Marshaller marshaller = JAXBContext.newInstance(Farm.class).createMarshaller(); marshaller.marshal(farm, document); SOAPMessage soapMessage = MessageFactory.newInstance().createMessage(); soapMessage.getSOAPBody().addDocument(document); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); soapMessage.writeTo(outputStream); String output = new String(outputStream.toByteArray()); 

Desmaterialización

 String example = ""; SOAPMessage message = MessageFactory.newInstance().createMessage(null, new ByteArrayInputStream(example.getBytes())); Unmarshaller unmarshaller = JAXBContext.newInstance(Farm.class).createUnmarshaller(); Farm farm = (Farm)unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument()); 

Aquí es cómo puede manejar su uso cae:

Si necesita Envelope elemento Envelope

paquete-información

Normalmente, usaría @XmlSchema siguiente manera. Usar las propiedades de namespace y elementFormDefault como lo he hecho significa que todos los datos asignados a elementos XML a menos que se asignen de otra manera pertenecerán al http://www.xxxx.com/ncp/oomr/dto/ namespace. La información especificada en xmlns es para la generación de esquemas XML, aunque algunas implementaciones de JAXB usan esto para determinar el prefijo preferido para un espacio de nombres cuando se hace una clasificación (ver: http://blog.bdoughan.com/2011/11/jaxb-and-namespace-prefixes .html ).

 @XmlSchema ( namespace="http://www.xxxx.com/ncp/oomr/dto/", elementFormDefault=XmlNsForm.QUALIFIED, xmlns = { @XmlNs(prefix = "env", namespaceURI="http://schemas.xmlsoap.org/soap/envelope/"), @XmlNs(prefix="whatever", namespaceURI="http://www.xxxx.com/ncp/oomr/dto/") } ) package com.one.two; import javax.xml.bind.annotation.*; 

Sobre

Si dentro de com.one.two necesita mapear elementos de un espacio de nombres que no sea http://www.xxxx.com/ncp/oomr/dto/ entonces debe especificarlo en las anotaciones @XmlRootElement y @XmlElement .

 package com.one.two; import javax.xml.bind.annotation.*; @XmlRootElement(name="Envelope", namespace="http://schemas.xmlsoap.org/soap/envelope/") @XmlAccessorType(XmlAccessType.FIELD) public class Envelope { @XmlElement(name="Body", namespace="http://schemas.xmlsoap.org/soap/envelope/") private Body body; } 

Para más información

Si solo quieres mapear el cuerpo

Puede usar un analizador StAX para analizar el mensaje y avanzar a la parte de carga útil y partir de allí:

 import javax.xml.bind.*; import javax.xml.stream.*; import javax.xml.transform.stream.StreamSource; public class UnmarshalDemo { public static void main(String[] args) throws Exception { XMLInputFactory xif = XMLInputFactory.newFactory(); StreamSource xml = new StreamSource("src/blog/stax/middle/input.xml"); XMLStreamReader xsr = xif.createXMLStreamReader(xml); xsr.nextTag(); while(!xsr.getLocalName().equals("return")) { xsr.nextTag(); } JAXBContext jc = JAXBContext.newInstance(Customer.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); JAXBElement jb = unmarshaller.unmarshal(xsr, Customer.class); xsr.close(); } } 

Para más información

Solo quería agregar a las respuestas existentes, mientras desmarca si el documento XML no es consciente del espacio de nombres, es posible que reciba un error: javax.xml.bind.UnmarshalException: elemento inesperado (uri: ” http: //some.url “; local: “someOperation”)

Si este es el caso, simplemente puede usar un método diferente en el unmarshaller:

 Unmarshaller unmarshaller = JAXBContext.newInstance(YourObject.class).createUnmarshaller(); JAXBElement element = unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument(), YourObject.class); YourObject yo = element.getValue();