Spring WS WebServiceTemplate: access to the content of the response or customising the unmarshaller (solved)

I am sending a message to an external SOAP service that should reply with a soap Message containing, among other things, an image. This is the code I wrote to send the message:

@Bean
Jaxb2Marshaller jaxb2Marshaller() {
    Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
    jaxb2Marshaller.setContextPath("myContextPath");

    return jaxb2Marshaller;
}

@Bean
public WebServiceTemplate webServiceTemplate() {
    WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
    webServiceTemplate.setMessageSender(webServiceMessageSender());
    webServiceTemplate.setMarshaller(jaxb2Marshaller());
    webServiceTemplate.setUnmarshaller(jaxb2Marshaller());
    webServiceTemplate.setDefaultUri(defaultUri);
    return webServiceTemplate;
}

public ProcessDocumentResponse sendRequest(MyRequest myRequest) {
    MyResponse response = (MyResponse) webServiceTemplate.marshalSendAndReceive(
            myRequest,
            message -> ((SoapMessage) message).setSoapAction(theAction));
    return response;
}

And this is the response, got from the log:

Receiving response: HTTP/1.1 200 OK
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: multipart/related; type="application/xop+xml";start="<http://tempuri.org/0>";boundary="uuid:_someUUID_";start-info="text/xml"
Server: Microsoft-IIS/10.0
MIME-Version: 1.0
X-AspNet-Version: ...
X-Powered-By: ...
Date: Wed, 11 Oct 2017 09:10:36 GMT
Content-Length: 228346
Connection can be kept alive indefinitely
"[\r][\n]"
"--uuid:_someUUID_[\r][\n]"
"Content-ID: <http://tempuri.org/0>[\r][\n]"
"Content-Transfer-Encoding: 8bit[\r][\n]"
"Content-Type: application/xop+xml;charset=utf-8;type="text/xml"[\r][\n]"
"[\r][\n]"
"<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body>
<here a long response and at some point:><OutputImages><ImageData><xop:Include href="cid:http://tempuri.org/1/636433219150087850" xmlns:xop="http://www.w3.org/2004/08/xop/include"/></ImageData><Metadata i:nil="true"/></OutputImages>
</s:Body></s:Envelope>[\r][\n]"
"--uuid:_someUUID_[\r][\n]"
"Content-ID: <http://tempuri.org/1/636433098360776690>[\r][\n]"
"Content-Transfer-Encoding: binary[\r][\n]"
"Content-Type: application/octet-stream[\r][\n]"
"[\r][\n]"
"[0xff][0xd8][0xff][0xe0][0x0]_here a long sequence o bytes representing an image_
<< "--uuid:_someUUID_[\r][\n]"

as you can see, there are two multipart contents. In the first multipart content there is the ImageData containing:

<OutputImages><ImageData><xop:Include href="cid:http://tempuri.org/1/636433219150087850" xmlns:xop="http://www.w3.org/2004/08/xop/include"/></ImageData><Metadata i:nil="true"/></OutputImages>

that link cid:http://tempuri.org/1/636433219150087850 is the ID of the second multipart content.

The problem is that after unmarshalling the message, my response contains a byte[] imageData that is empty but should contain the bytes in the second multipart content. So I don't exactly know how to face this problem, should I change some configuration to the unmarshaller? (how?) Should I access the HttpResponse (how?), but then how can I fill the byte[] value in the response?

Any help/suggestion is much appreciated.

1 answer

  • answered 2017-10-11 13:30 marco

    After a bit of struggling, I found the solution. The key was to understand how this mechanism is called, I ignored it, shame on me.

    It is called MTOM and the solution of my problem is just a row more in the marshaller creation:

        @Bean
        Jaxb2Marshaller jaxb2Marshaller() {
            Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
            jaxb2Marshaller.setContextPath("myContextPath");
            jaxb2Marshaller.setMtomEnabled(true); //that's it!!
    
            return jaxb2Marshaller;
        }
    

    I found the solution when I bumped into this post, and then looking for the meaning of MTOM and finally the solution in the Spring WS Documentation