How to unmarshall SOAP response using JAXB if namespace declaration is on SOAP envelope?

后端 未结 2 1394
既然无缘
既然无缘 2020-12-13 20:14

JAXB can only unmarshall an XML if the soap envelope has already been removed. However, the SOAP response I\'m trying to unmarshall has its namespace declaration on the soap

相关标签:
2条回答
  • 2020-12-13 20:48

    You can use a StAX parser to parse the SOAP message and then advance the XMLStreamReader to the getNumberResponse element and use the unmarshal method that takes a class parameter. A StAX parser is included in Java SE 6, but you will need to download one for Java SE 5. Woodstox is a popular StAX parser.

    Response

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

    Demo

    An XMLStreamReader has a NamespaceContext. The NamespaceContext knows all the active namespace declarations for the current level. Your JAXB (JSR-222) implementation will be able to leverage this to get the necessary information.

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

    Output

    http://example.com/
    {http://example.com/}getNumberResponse
    forum11465653.Response@781f6226
    
    0 讨论(0)
  • 2020-12-13 20:52

    You could parse the whole SOAP message using a DOM parser, which would be able to resolve all the namespaces at parse time. Then extract the element you require from the resulting DOM tree and pass that to the 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());
        }
    
    }
    

    Output

    {http://example.com/}getNumberResponse
    forum11465653.Response@19632847
    
    0 讨论(0)
提交回复
热议问题