Danny Gloudemans
Danny Gloudemans

Reputation: 2677

SOAP field is always return null as value

We have SOAP response and I'm trying to unmarshal this or just getting the value from the namesp1:result field, but I'm always getting the value null, while in the response the value is set to D.

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
        <namesp1:CheckTransactionDetailsResponse xmlns:namesp1="http://www.iesnare.com/dra/api/CheckTransactionDetails">
            <namesp1:result xsi:type="xsd:string">D</namesp1:result>
            <namesp1:reason xsi:type="xsd:string"/>
            <namesp1:trackingnumber xsi:type="xsd:string">646498141355</namesp1:trackingnumber>
            <namesp1:endblackbox xsi:type="xsd:string"/>
            <namesp1:details>
                <namesp1:detail>
                    <namesp1:name>device.cookie.enabled</namesp1:name>
                    <namesp1:value>1</namesp1:value>
                </namesp1:detail>
                <namesp1:detail>
                    <namesp1:name>device.flash.enabled</namesp1:name>
                    <namesp1:value>0</namesp1:value>
                </namesp1:detail>
                <namesp1:detail>
                    <namesp1:name>device.flash.installed</namesp1:name>
                    <namesp1:value>0</namesp1:value>
                </namesp1:detail>
                <namesp1:detail>
                    <namesp1:name>device.js.enabled</namesp1:name>
                    <namesp1:value>0</namesp1:value>
                </namesp1:detail>
                <namesp1:detail>
                    <namesp1:name>device.os</namesp1:name>
                    <namesp1:value>UNKNOWN</namesp1:value>
                </namesp1:detail>
                <namesp1:detail>
                    <namesp1:name>ipaddress</namesp1:name>
                    <namesp1:value>127.0.0.1</namesp1:value>
                </namesp1:detail>
                <namesp1:detail>
                    <namesp1:name>realipaddress</namesp1:name>
                    <namesp1:value>127.0.0.1</namesp1:value>
                </namesp1:detail>
                <namesp1:detail>
                    <namesp1:name>realipaddress.source</namesp1:name>
                    <namesp1:value>subscriber</namesp1:value>
                </namesp1:detail>
                <namesp1:detail>
                    <namesp1:name>ruleset.rulesmatched</namesp1:name>
                    <namesp1:value>0</namesp1:value>
                </namesp1:detail>
                <namesp1:detail>
                    <namesp1:name>ruleset.score</namesp1:name>
                    <namesp1:value>0</namesp1:value>
                </namesp1:detail>
            </namesp1:details>
        </namesp1:CheckTransactionDetailsResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

I have used the following code snippets:

  1. Get element by tagnameNS, the response is as follows:

    Name namesp1:result
    Value: null
    

Used Java code:

    SOAPBody sb = soapResponse.getSOAPBody();
    Document d = sb.extractContentAsDocument();
    NodeList nodeList = d.getElementsByTagNameNS("http://www.iesnare.com/dra/api/CheckTransactionDetails", "result");

    for (int i = 0; i < nodeList.getLength(); i++) {
        org.w3c.dom.Node nodeElement = nodeList.item(i);
        System.out.println("Name " + nodeElement.getNodeName());
        System.out.println("Value: " + nodeElement.getNodeValue());
    }
  1. Unmarshal response to object, which I think is the best way to do this. But then I'm getting the following exception.

    Error occurred while sending SOAP Request to Server
    java.lang.IllegalArgumentException: prefix xsd is not bound to a namespace
    

Used Java code:

    SOAPBody sb = soapResponse.getSOAPBody();
    Document d = sb.extractContentAsDocument();
    DOMSource source = new DOMSource(d);
    CheckTransactionDetailsResponse checkTransactionDetailsResponse = (CheckTransactionDetailsResponse) JAXB.unmarshal(source, CheckTransactionDetailsResponse.class);
    System.out.println();
    System.out.println();
    System.out.println("Result: " + checkTransactionDetailsResponse.getResult());
    System.out.println();
    System.out.println();

Can someone help me to find the correct way to get the response, I prefer to use method 2 but I saw something on internet that this is a bug in JAXB.

Thanks

Upvotes: 0

Views: 1747

Answers (1)

Valentino
Valentino

Reputation: 138

Method 1: If you read the documentation for Node, you will realize that Node.getNodeValue() will always return null for Element nodes (check the table at the top of the page).

The reason is that there is no "value" concept for XML elements; the value as you intend (the letter D) is a child node (a text node) of that element. You must iterate through children nodes, filtering text ones, to get your value.

Method 2: Here the problem derives from the current JAXB implementation of DOMSource. Sparing the details, the reason is that the namespace declaration is present at Envelope level; when you strip the body, that declaration is lost on serialization of that DOM.

To have it back use a combination of @XmlSchemaand @XmlNs annotations in package-info.java of the package containing your schema classes.

Upvotes: 2

Related Questions