Skip to content
Advertisement

Unmarshal SOAP response with CDATA in its body using JAXB

I am trying to unmarshal a SOAP respone using JAXB but without success. What I have so far are the model classes generated using an xsd and the following code which should unmarshal the response:

SOAPBody soapBody = soapResponse.getSOAPBody();
// Next line should get me to bspQuittung element from response
DOMSource domSource = new DOMSource(soapBody.getFirstChild().getFirstChild());
JAXBContext jaxbContext = JAXBContext.newInstance(BspQuittung.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
BspQuittung bspQuittung = jaxbUnmarshaller.unmarshal(domSource, BspQuittung.class).getValue();

Then I try to access the value of the <AnnahmeErfolgreich> element but instead of being true like in the response the object which unmarshaller gives me has the value for it being false.

What am I missing? Trying to get deeper by calling getFirstChild() again results in an Unexpected node type: com.sun.xml.messaging.saaj.soap.impl.SOAPTextImpl exception.

Below is the response itself:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <ns2:sendBspNachrichtNativeOutput xmlns:ns2="somevalue">
         <bspQuittung><![CDATA[<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<BspQuittung version="1.5" fassung="2020-03-15" xmlns="somevalue">
    <AnnahmeErfolgreich>true</AnnahmeErfolgreich>
    <ErgebnisStatus>
        <Tabelle>someInt</Tabelle>
        <Schluessel>someInt</Schluessel>
    </ErgebnisStatus>
</BspQuittung>]]></bspQuittung>
      </ns2:sendBspNachrichtNativeOutput>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

How can I change the code to get the unmarshaller work as expected? Thank you!

Advertisement

Answer

I had to use an XMLStreamReader as answered here but instead of file I also used an InputStream:

     SOAPBody soapBody = soapResponse.getSOAPBody();
     XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
     Node soapBodyChild = soapBody.getFirstChild();
     String bspQuittungAsXmlString = soapBodyChild.getFirstChild().getFirstChild().getNodeValue();
     byte[] bspQuittungAsByteArray = bspQuittungAsXmlString.getBytes(StandardCharsets.UTF_8);
     ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bspQuittungAsByteArray);
     InputStreamReader inputStreamReader = new InputStreamReader(byteArrayInputStream);
     XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(inputStreamReader);
     JAXBContext jaxbContext = JAXBContext.newInstance(BspQuittung.class);
     Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
     BspQuittung bspQuittung = jaxbUnmarshaller.unmarshal(xmlStreamReader, BspQuittung.class).getValue();
     xmlStreamReader.close();
     inputStreamReader.close();
     byteArrayInputStream.close();

After this the variable bspQuittung had the right values.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement