How to unmarshall SOAP XML to Java Object

55,678

I don't think you're taking the SOAP envelope into account... Your generated JAXB Unmarshaller won't know anything about the Body or Envelope tags, it will be expecting your createSession to be the root element hence the "unexpected element" error.

You need to extract the content from the Envelope first, you can do this with message.getSOAPBody().extractContentAsDocument() if you create a SOAPMessage object from your content first.

It's quite fiddly to do, here's a working example from my blog

String example =
        "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Header /><soapenv:Body><ns2:farm xmlns:ns2=\"http://adamish.com/example/farm\"><horse height=\"123\" name=\"glue factory\"/></ns2:farm></soapenv:Body></soapenv:Envelope>";
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());

It seems that if you don't declare your namespace in your schema .xsd file then you'll see the error you have.

I created a dummy schema with a root element createSession and by adding the targetNamespace attribute and regenerating the JAXB classes the error disappeared

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     targetNamespace="http://example.com/v2"> <!-- targetNamespace essential for JAXB to work-->
    <xs:element name="createSession">  
        <xs:complexType>
            <xs:attribute name="foo" type="xs:string" use="required" />
        </xs:complexType>
    </xs:element>
</xs:schema>
Share:
55,678
srinath
Author by

srinath

Updated on September 30, 2020

Comments

  • srinath
    srinath over 3 years

    while trying to unmarshall my soap XML to JAXB object am getting the following error.

    We are getting error that expected element is none. Should anything specific be done while unmarshalling the SOAP XML.

    javax.xml.bind.JAXBContext jaxbContext = (javax.xml.bind.JAXBContext) JAXBContext.newInstance(Class.forName(requestName));
    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
    StringReader reader = new StringReader(SoapXmlString);          
    reqInfo = unmarshaller.unmarshal(reader);
    

    Am getting the following error :

     javax.xml.bind.UnmarshalException: unexpected element (uri:"http://schemas.xmlsoap.org/soap/envelope/", local:"Envelope"). Expected elements are (none)
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:642)
        at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:254)
        at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:249)
        at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:116)
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement
    

    and here is the sample XML

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v2="http://example.com/v2">
           <soapenv:Header/>
           <soapenv:Body>
              <v2:createSession>
                 <v2:client>
                    <!--Optional:-->
                    <v2:name>?</v2:name>
                    <!--Optional:-->
                    <v2:clientId>?</v2:clientId>
                    <!--Optional:-->
                    <v2:requestId>?</v2:requestId>
                 </v2:client>
                 <!--Optional:-->
                 <v2:oldSessionId>?</v2:oldSessionId>
                 <!--Optional:-->
                 <v2:clientIp>?</v2:clientIp>
                 <!--Optional:-->
                 <v2:clientIpStatus>?</v2:clientIpStatus>
                 <!--Optional:-->
                 <v2:superBYOBFlow>?</v2:superBYOBFlow>
                 <!--Optional:-->
                 <v2:FlowParams>?</v2:FlowParams>
                 <!--Optional:-->
                 <v2:deviceInfo>?</v2:deviceInfo>
              </v2:createSession>
           </soapenv:Body>
        </soapenv:Envelope>
    

    Please do help .

    • Priyesh
      Priyesh over 9 years
      What value does 'requestName' have?
    • Paul Samsotha
      Paul Samsotha over 9 years
      See here.
    • srinath
      srinath over 9 years
      @priyesh : its a class name . Ex: createSessionRequest
    • DarthPablo
      DarthPablo almost 9 years
      I'm probably going blind (likely), but I can't see the link to the duplicate answer?!?
  • srinath
    srinath over 9 years
    Thanks for your help .. i tried the same code by replacing the Farm class by CreateSessionRequest class . But am getting following error again . javax.xml.bind.UnmarshalException: unexpected element (uri:"example.com/v2", local:"createSession"). Expected elements are (none)
  • Adam
    Adam over 9 years
    @srinath Can you post your .xsd file and I'll have a closer look.