Home > Mobile >  springboot SOAP producer - list of objects on input always empty
springboot SOAP producer - list of objects on input always empty

Time:04-11

I am facing a problem trying to produce a SOAP web service in Springboot with list of objects as input.

When I call the service scalar values are being unmarshalled, but the list contains only empty arrays.

I cannot figure out what I am missing.... I cannot change the WSDL definition.

It is a bit hard to follow, so I reproduced the problem on Github.

Here is my Endpoint definition. As soon as code hits the doc.getDocFormat().getValue() part, trying to read from list, it throws Cannot invoke "javax.xml.bind.JAXBElement.getValue(), basically a NullPointerException.

@Endpoint
public class MergeTiffEndpoint {
    private static final String NAMESPACE_URI = "urn:Gekon";

    Logger logger = LoggerFactory.getLogger(MergeTiffEndpoint.class);

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "MERGE_TIFFRequestElement")
    @ResponsePayload
    public MERGETIFFReturn merge(@RequestPayload MERGETIFFQuery request) {

        List<InputSetRow> list = request.getDocuments().getValue().getDocument();

        logger.info("List size is "   list.size());

        list.forEach((doc) ->
                System.out.println("Value is "   doc.getDocFormat().getValue())
        );

        return null;
    }
}

This is call from client:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <ns1:MERGE_TIFFRequestElement xmlns:ns1="urn:Gekon">
            <ns1:documents xsi:type="ns1:InputSet">
                <ns1:document xsi:type="ns1:InputSetRow">
                    <doc_format xsi:type="xsd:string">TIFF</doc_format>
                    <location xsi:type="xsd:string">c:\Users\zizam\private\gekonTests\file-convertor\files\input\merge_tiff_single.tif</location>
                    <options xsi:nil="true"/>
                </ns1:document>
                <ns1:document xsi:type="ns1:InputSetRow">
                    <doc_format xsi:type="xsd:string">TIFF</doc_format>
                    <location xsi:type="xsd:string">c:\Users\zizam\private\gekonTests\file-convertor\files\input\merge_tiff_multi.tif</location>
                    <options xsi:nil="true"/>
                </ns1:document>
            </ns1:documents>
            <ns1:storage_type xsi:type="xsd:string">URL</ns1:storage_type>
            <ns1:appl_id xsi:type="xsd:string">MQT_TEST</ns1:appl_id>
        </ns1:MERGE_TIFFRequestElement>
    </soapenv:Body>
</soapenv:Envelope>

I used jaxb2-maven-pluginand generated pojo stubs from wsdl file.

Following relevant classes were poduced:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "MERGE_TIFFQuery", propOrder = {
    "documents",
    "storageType",
    "applId"
})
public class MERGETIFFQuery {

    @XmlElementRef(name = "documents", namespace = "urn:Gekon", type = JAXBElement.class, required = false)
    protected JAXBElement<InputSet> documents;
    @XmlElementRef(name = "storage_type", namespace = "urn:Gekon", type = JAXBElement.class, required = false)
    protected JAXBElement<String> storageType;
    @XmlElementRef(name = "appl_id", namespace = "urn:Gekon", type = JAXBElement.class, required = false)
    protected JAXBElement<String> applId;

-- standard getters and setters
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "InputSet", propOrder = {
    "document"
})
public class InputSet {

    @XmlElement(nillable = true, namespace = "urn:Gekon")
    protected List<InputSetRow> document;

    public List<InputSetRow> getDocument() {
        if (document == null) {
            document = new ArrayList<InputSetRow>();
        }
        return this.document;
    }
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "InputSetRow", propOrder = {
    "docFormat",
    "location",
    "options",
    "content"
})
@XmlRootElement
public class InputSetRow {

    @XmlElementRef(name = "doc_format", namespace = "urn:Gekon", type = JAXBElement.class, required = false)
    protected JAXBElement<String> docFormat;
    @XmlElementRef(name = "location", namespace = "urn:Gekon", type = JAXBElement.class, required = false)
    protected JAXBElement<String> location;
    @XmlElementRef(name = "options", namespace = "urn:Gekon", type = JAXBElement.class, required = false)
    protected JAXBElement<String> options;
    @XmlElementRef(name = "content", namespace = "urn:Gekon", type = JAXBElement.class, required = false)
    protected JAXBElement<Base64Binary> content;

-- standard getters and setters

I really don;t know what I am missing.
Any help appreciated.

CodePudding user response:

Ok, figured it out.

The call which is issued by client doesn't have namespace reference.

<ns1:document xsi:type="ns1:InputSetRow">
   <ns1:doc_format xsi:type="xsd:string">TIFF</doc_format>
   <location xsi:type="xsd:string">c:\Users\zizam\private\gekonTests\file-convertor\files\input\merge_tiff_single.tif</location>
   <options xsi:nil="true"/>
</ns1:document>

When I make a call in format ns1:doc_format, everything works ok. So the only way to get it working was to change namespace references in InutSetRow to InputSetRow to namespace = ""

  • Related