marshaller marshal example java xml soap jaxb unmarshalling

java - marshal - ¿Cómo separar la respuesta SOAP usando JAXB si la declaración del espacio de nombres está en el sobre SOAP?



marshaller java example (2)

Podría analizar todo el mensaje SOAP utilizando un analizador DOM, que podría resolver todos los espacios de nombres en tiempo de análisis. A continuación, extraiga el elemento que necesita del árbol DOM resultante y páselo al unmarshaller.

DomDemo

package forum11465653; import java.io.File; import javax.xml.bind.*; import javax.xml.parsers.*; import javax.xml.transform.dom.DOMSource; import org.w3c.dom.*; public class DomDemo { public static void main(String[] args) throws Exception{ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); DocumentBuilder db = dbf.newDocumentBuilder(); Document d = db.parse(new File("src/forum11465653/input.xml")); Node getNumberResponseElt = d.getElementsByTagNameNS("http://example.com/", "getNumberResponse").item(0); JAXBContext jc = JAXBContext.newInstance(Response.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); JAXBElement<Response> je = unmarshaller.unmarshal(new DOMSource(getNumberResponseElt), Response.class); System.out.println(je.getName()); System.out.println(je.getValue()); } }

Salida

{http://example.com/}getNumberResponse forum11465653.Response@19632847

JAXB solo puede deshacer un XML si el sobre de jabón ya se ha eliminado. Sin embargo, la respuesta SOAP que trato de deshacer tiene su declaración de espacio de nombres en el sobre del jabón. Si elimino el sobre de jabón, también se eliminará la declaración del espacio de nombres. Como tal, el prefijo de las etiquetas se referirá a none. Esto hace que JAXB arroje un error. ¿Cómo puedo deshacer una respuesta SOAP utilizando JAXB si el espacio de nombres está declarado en el sobre SOAP?

Una muestra similar del XML que necesito deshacer es la siguiente:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://example.com/"> <soapenv:Body> <ns:getNumberResponse> <number>123456789</number> </ns:getNumberResponse> </soapenv:Body> </soapenv:Envelope>

Esto es lo que sucede si elimino el sobre de jabón:

<ns:getNumberResponse> <number>123456789</number> </ns:getNumberResponse>

Si eliminé el sobre del jabón, la declaración del espacio de nombres también desaparecerá. JAXB no podrá deshacer el xml anterior porque falta la definición de espacio de nombres para el prefijo "ns". Como tal, devolverá un "The prefix "ns" for element "ns:getNumberResponse" is not bound." mensaje de error. ¿Cómo lo arreglo?

Tenga en cuenta que estoy usando JDK 1.5. No estoy seguro si hay una manera de resolver esto en JDK 1.6. Pude usar JAXB porque descargué los archivos necesarios para usar JAXB.


Puede usar un analizador StAX para analizar el mensaje SOAP y luego avanzar el XMLStreamReader al elemento getNumberResponse y usar el método unmarshal que toma un parámetro de clase. Un analizador StAX está incluido en Java SE 6, pero deberá descargar uno para Java SE 5. Woodstox es un analizador StAX popular.

Respuesta

package forum11465653; public class Response { private long number; public long getNumber() { return number; } public void setNumber(long number) { this.number = number; } }

Manifestación

Un XMLStreamReader tiene un NamespaceContext . NamespaceContext conoce todas las declaraciones activas del espacio de nombres para el nivel actual. Su implementación JAXB (JSR-222) podrá aprovechar esto para obtener la información necesaria.

package forum11465653; import java.io.FileReader; import javax.xml.bind.*; import javax.xml.stream.*; public class Demo { public static void main(String[] args) throws Exception{ XMLInputFactory xif = XMLInputFactory.newFactory(); XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("src/forum11465653/input.xml")); xsr.nextTag(); // Advance to Envelope tag xsr.nextTag(); // Advance to Body tag xsr.nextTag(); // Advance to getNumberResponse tag System.out.println(xsr.getNamespaceContext().getNamespaceURI("ns")); JAXBContext jc = JAXBContext.newInstance(Response.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); JAXBElement<Response> je = unmarshaller.unmarshal(xsr, Response.class); System.out.println(je.getName()); System.out.println(je.getValue()); } }

Salida

http://example.com/ {http://example.com/}getNumberResponse forum11465653.Response@781f6226