[INT-1800] MTOM Support Created: 14/Feb/11  Updated: 05/Apr/17  Resolved: 01/Mar/17

Status: Closed
Project: Spring Integration
Component/s: Web Services
Affects Version/s: 2.0.3
Fix Version/s: 5.0 M3

Type: Improvement Priority: Minor
Reporter: Russell Hart Assignee: Artem Bilan
Resolution: Complete Votes: 4
Labels: PullRequest
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
supersedes INT-3775 MTOM attachment lost by SimpleWebServ... Closed
Reference URL: http://forum.springsource.org/showthread.php?t=103434
Pull Request URL: https://github.com/spring-projects/spring-integration/pull/2060


It would be great if SI had MTOM support. Whether that be receiving MTOM attachments and maybe adding them as a message header?? Or sending SOAP responses with MTOM attachments. See the forum reference so my specific use case.

Comment by Mark Fisher [ 14/Feb/11 ]

This might end up being a 2.1 feature, but I'm adding it to 2.0.4 so we at least explore that option.

Comment by Mark Fisher [ 18/Apr/11 ]

moving target to 2.1

Comment by Artem Bilan [ 20/Jul/15 ]

Hello, Mauro Molinari!

Let me know if this will work for you:

<ws:inbound-gateway extract-payload="false"/>

Where a payload of the message for request-channel is the whole WebServiceMessage and in case of multipart request it is MimeMessage and that, frankly can be used for proper unmarshaling using MarshallingUtils. I really not sure that it will work with standard int-xml:unmarshalling-transformer.

If you need, we can come up here with some test-case on the matter to see what's going on from request perspective.

I worry in this JIRA more about the response part, where we like to send MTOM attachment back to requestor.
In this case we should support WebServiceMessage as a valid reply message type. The attachments must be populated in that WebServiceMessage manually before sending back to the <ws:inbound-gateway>.

Feel free to share your ideas on the matter.
And, of course, contributions are welcome!

Comment by Mauro Molinari [ 20/Jul/15 ]

Hi Artem,
this ticket seems to be a bit vague, in the sense that, as I outlined in INT-3775, a way to receive MTOM attachments properly is to use a MarshallingWebServiceInboundGateway properly configured with a MTOM-enabled (un)marshaller, so MTOM support (at least for the receiving part) in SI actually exists. I have not yet adventured myself with responses, so I can't provide any feedback on that.
What I saw is the inconsistency with the use of SimpleWebServiceInboundGateway followed by an unmarshalling transformer (which uses the exact same MTOM-enabled unmarshaller of the first case) in place of the MarshallingWebServiceInboundGateway.
Honestly, I didn't try the extract-payload attribute (it was not mentioned in the reference documentation), it may be interesting to see if it works. I'll try as soon as possible, although I doubt it will work with int-xml:unmarshalling-transformer, which I suppose expects just a Source instance.
One thing I was thinking about is that, if a plain Source on the request channel can't carry the MTOM attachments by itself, probably finding a way to support unmarshalling of a whole WebServiceMessage with a dedicated tag wouldn't be worth the effort: once again, just a good documentation on this topic could be enough to guide the user on how to do this task (i.e.: properly handling incoming messages containing MTOM attachments).
On the other hand, if some smart way to "convert" the WebServiceMessage into a "plain" Source with (inlined?) attachments, processable by a simple int-xml:unmarshalling-transformer, could be found, well it might be more interesting. But I really don't know what this may mean in terms of performance and memory consumption (the whole attachment should probably be put on the request channel in any case, so I would say it wouldn't make any difference... but I really don't know how these things are handled at low level).

Comment by Artem Bilan [ 20/Jul/15 ]

Mauro, thank you for the feedback one more time!

Here you are my further investigations and thoughts.

The MarshallingWebServiceInboundGateway uses this code to unmarshal the request:

WebServiceMessage request = messageContext.getRequest();
Assert.notNull(request, "Invalid message context: request was null.");
Object requestObject = MarshallingUtils.unmarshal(unmarshaller, request);

Where the last one has the code:

else if (unmarshaller instanceof MimeUnmarshaller && message instanceof MimeMessage) {
	MimeUnmarshaller mimeUnmarshaller = (MimeUnmarshaller) unmarshaller;
	MimeMessageContainer container = new MimeMessageContainer((MimeMessage) message);
	return mimeUnmarshaller.unmarshal(payload, container);

The Jaxb2Marshaller is exactly of that MimeUnmarshaller and the WebServiceMessage is of that MimeMessage type.
So, if we will be able to teach our UnmarshallingTransformer (<int-xml:unmarshalling-transformer>) to get deal with MimeMessage, we will reach your requirements with SimpleWebServiceInboundGateway and unmarshaller pair. Although this sample doesn't look promising, but I'm sure there might me other cases, when we should get deal with WebServiceMessage directly from one side and can marshal/unmarshal any MimeContainer (see its JavaDocs for more info) on the transformer side.

Comment by Mauro Molinari [ 21/Jul/15 ]

Indeed, I just tried to simply add extract-payload="false" to the inbound gateway and see if <int-xml:unmarshalling-transformer> works, but it doesn't, as we expected: a fault is returned saying "failed to create Source for payload type [org.springframework.ws.soap.saaj.SaajSoapMessage]".

So, possible solutions are:

  • enhance <int-xml:unmarshalling-transformer> to also handle MimeMessage payloads, at least if the unmarshaller is a MimeUnmarshaller
  • provide something like a <int-ws:mime-unmarshalling-transformer> to do that (probably not very elegant, however...)
  • make SimpleWebServiceInboundGateway automatically inline the attachments into the Source instance returned with extract-payload="true" (at least optionally)
  • just document the possible solutions at the moment
Comment by Artem Bilan [ 21/Jul/15 ]

Everything sounds good, unless the last two items.

I'm afraid that we won't be able to provide some Source implementation.
And looking to the MimeUnmarshaller implementation I don't see any other solution unless process attachments manually and directly from the MimeMessage, which will be available just after extract-payload="false".

We will document it anyway when we implement the proper solution, which doesn't look so complex already after this our with you investigation.

Comment by Artem Bilan [ 10/Aug/16 ]

On the outbound part I marked code as:

public Object doExtractData(WebServiceMessage message) throws IOException, TransformerException {
	// TODO Add option to return a full WebServiceMessage as a payload. For symmetry with inbound extractPayload
	Source payloadSource = message.getPayloadSource();
Generated at Fri Feb 22 02:51:27 UTC 2019 using JIRA 7.9.2#79002-sha1:3bb15b68ecd99a30eb364c4c1a393359bcad6278.