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-plugin
and 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 = ""