Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 323
marco Avatar asked Oct 11 '17 10:10

marco


People also ask

What is the use of WebServiceTemplate?

Class WebServiceTemplate. The central class for client-side Web services. It provides a message-driven approach to sending and receiving WebServiceMessage instances. Code using this class need only implement callback interfaces, provide Source objects to read data from, or use the pluggable Marshaller support.

Is Spring WebServiceTemplate thread safe?

Please note that the WebServiceTemplate class is thread-safe once configured (assuming that all of it's dependencies are thread-safe too, which is the case for all of the dependencies that ship with Spring-WS), and so multiple objects can use the same shared WebServiceTemplate instance if so desired.

What is SoapActionCallback used for?

Class SoapActionCallback. WebServiceMessageCallback implementation that sets the SOAP Action header on the message. A usage example with WebServiceTemplate : WebServiceTemplate template = new WebServiceTemplate(messageFactory); Result result = new DOMResult(); template.

What is WebServiceGatewaySupport?

WebServiceGatewaySupport() Creates a new instance of the WebServiceGatewaySupport class, with a default WebServiceTemplate . protected. WebServiceGatewaySupport(WebServiceMessageFactory messageFactory) Creates a new WebServiceGatewaySupport instance based on the given message factory.


1 Answers

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

like image 121
marco Avatar answered Jan 03 '23 05:01

marco