Search code examples
javaspringjaxbwsdl

Java, WSDL generated class cannot be cast to javax.xml.bind.JAXBElement


I am getting back an javax.xml.bind.JAXBElementexception after calling a web service.

JAXBElement<ShowPendingFiles> jAXBElement = new ObjectFactory().createShowPendingFiles(showPendingFilesRequest);

CustomEnvelopeDetails customEnvelopeDetails = new CustomEnvelopeDetails(
    CcrConstants.ACTION_PENDING_FILES,
    new SecurityHeader(isSecurityEnabled, username, password)
        );

final Object marshalled = (ShowPendingFilesResponse) createServiceTemplate(jaxb2Marshaller)
//return (ShowPendingFilesResponse) createServiceTemplate(jaxb2Marshaller)
    .marshalSendAndReceive(soapServer, jAXBElement,
          new SoapRequestHeaderModifier(customEnvelopeDetails));
return (ShowPendingFilesResponse) marshalled;

The web service reponds with 200 OK and the response in XML is

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <ns2:showPendingFilesResponse
            xmlns:ns2="http://iris.somewhere.com/web_services/external/downloadFile"
            xmlns:ns3="http://iris.somewhere.gr/web_services/external/uploadFile"/>
    </soapenv:Body>
</soapenv:Envelope>

which is correct, since there are no "files available to download" yet.

However the marshalSendAndReceive fails to marshal the response.

I am getting the following exception:

javax.xml.bind.JAXBElement cannot be cast to download.iris.models.ShowPendingFilesResponse

The auto generated (from WSDL) JAX class is this one

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "showPendingFilesResponse", propOrder = {
    "showPendingFilesResult"
})
public class ShowPendingFilesResponse {

    @XmlElement(nillable = true)
    protected List<TransferableFile> showPendingFilesResult;

   
    public List<TransferableFile> getShowPendingFilesResult() {
        if (showPendingFilesResult == null) {
            showPendingFilesResult = new ArrayList<TransferableFile>();
        }
        return this.showPendingFilesResult;
    }

} 

Solution

  • As you can see from the request you are sending

    JAXBElement<ShowPendingFiles> jAXBElement = new ObjectFactory().createShowPendingFiles(showPendingFilesRequest);
    

    The request is wrapped in a JAXBElement for the response you need to do the inverse unwrap it. As the result you are getting is (judging from the exception you are getting) a JAXBElement<ShowPendingFilesResponse> and not a ShowPendingFilesResponse directly.

    Modify your code accordingly.

    final JAXBElement<ShowPendingFilesResponse> marshalled = (JAXBElement<ShowPendingFilesResponse>) createServiceTemplate(jaxb2Marshaller)
        .marshalSendAndReceive(soapServer, jAXBElement, new SoapRequestHeaderModifier(customEnvelopeDetails));
    return marshalled.getValue();