Submitting MTOM Attachment to SOAP Webservice

Don’t forget to tell us about your stack!

OS: Windows
Java Version: “1.8.0_241”
Tomcat Version: 9.0.14
Lucee Version: 5.3.7.48

Hi All,

I have a requirement to upload a binary attachment for a SOAP webservice using MTOM. I am wondering if anyone has manage to get this working without hitting the underlying java layer, and if so would be willing to help out?

MTOM:
https://www.w3.org/TR/soap12-mtom/

The xml soap document would look something like this:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"></SOAP-ENV:Envelope>
    <SOAP-ENV:Header></SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <SaveRequest xmlns="http://www.abacus.ch/abaconnect/2007.10/core/AbaConnectTypes">
            <AbaConnectParam>
                <Login>
                    <LoginToken>...</LoginToken>
                </Login>
                <Revision>0</Revision>
                <Level>Warning</Level>
                <Additional>
                    <StringData Name="ACIncludeExtendedFields">all</StringData>
                </Additional>
            </AbaConnectParam>
            <Data>
                <DocumentDossier mode='SAVE'>
                    <Number>13518</Number>
                    <Dossier mode='SAVE'>
                        <DossierName>BELEGE</DossierName>
                        <DocumentName>beleg_13518</DocumentName>
                    </Dossier>
                </DocumentDossier>
                <Attachment>
                    <BinaryData>
                        <Name>beleg_13518.pdf</Name>
                        <BinData xmime:contentType="application/octet-stream">
                            <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:a2b91634-7bc0-4a55-8355-934cbe871205@example.jaxws.sun.com"></xop:Include>
                        </BinData>
                </Attachment>
            </Data>
        </SaveRequest>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

where the “cid:” would be then referenced as a http header content-id

I found a pretty good example on soapui.org SOAP Attachments and Files | SoapUI which shows that we have to use multipart/related using different content-types and content-id’s to specify the document boundries.

Has anyone done something like this I would really appreciate some insights.

Cheers,

Gary

Anyone Have any ideas? I have no clue how to accomplish this and wouldn’t know where to begin trying to replicate this using the underlying java classes.

Could really use some help.

MTOM is new to me, so I read your link, then went to a more generic source.

MTOM only optimizes element content that is in the canonical lexical representation of the xs:base64Binary data type. Since there is no standard way to indicate whether data is in the canonical lexical representation, the mechanism for applying MTOM is implementation-dependent

From what you posted, it sounds like the starting point is to create your xml and convert to binary. I’m not sure what is needed for the transmission portion which I’m guessing is the bulk of your need?

Hi Jason,

xml is created, pdf is ready the issue is trying to get the http message to look like it is supposed to, that means in the body of the http post is the xml, and then a binary attachment in a separate boundry.

In the end the http post should look something like this:

Content-Type: Multipart/Related; start-info="text/xml"; type="application/xop+xml"; boundary="----=_Part_0_1744155.1118953559416"
Content-Length: 3453
SOAPAction: "save"

------=_Part_1_4558657.1118953559446
Content-Type: application/xop+xml; type="text/xml"; charset=utf-8

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"></SOAP-ENV:Envelope>
    <SOAP-ENV:Header></SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <SaveRequest >
            <AbaConnectParam>
                <Login>
                    <LoginToken>...</LoginToken>
                </Login>
            </AbaConnectParam>
            <Data>
                <DocumentDossier mode='SAVE'>
                    <Number>13518</Number>
                    <Dossier mode='SAVE'>
                        <DossierName>BELEGE</DossierName>
                        <DocumentName>beleg_13518</DocumentName>
                    </Dossier>
                </DocumentDossier>
                <Attachment>
                    <BinaryData>
                        <Name>beleg_13518.pdf</Name>
                        <BinData xmime:contentType="application/octet-stream">
                            <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:a2b91634-7bc0-4a55-8355-934cbe871205@example.jaxws.sun.com"></xop:Include>
                        </BinData>
                    </BinaryData>
                </Attachment>
            </Data>
        </SaveRequest>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

------=_Part_1_4558657.1118953559446
Content-Type: application/pdf
Content-ID: <a2b91634-7bc0-4a55-8355-934cbe871205@example.jaxws.sun.com>


... binary data ...

You notice that the first line we set up the content type for as application/xop+xml and the message boundry is defined for the xml, then the second part of the message is we identify the content-type of the attachment and specify the content-id which will tell the server on the other end when they process the xml that there is a binary attachment.

My problem is I have no clue how to set this up, with either cfml or java. Ive taken a look at Apache httpclient and know that there is a MultipartEntityBuilder and an EntityBuilder where you can define boundries and content types etc. but no idea how to generate and actually send the httprequest in the manner above…

Frankly, I’m stumped - and I really hate to admit that I can’t figure it out on my own :slight_smile:

Cheers,

Gary

1 Like

That reminds me pretty much mail message attachements. Without looking too much into it, don’t you need to add also a closing boundary at the bottom? Something like this:

------=_Part_1_4558657.1118953559446
Content-Type: application/pdf
Content-ID: <a2b91634-7bc0-4a55-8355-934cbe871205@example.jaxws.sun.com>


... binary data ...
------=_Part_1_4558657.1118953559446

Did you see this german example?

Thanks for the link, you are probably right with the 2nd boundary, but to be honest I don’t know …

Kinda need a concrete example and the only examples i found so far were either using java decorators in spring Apps or some license java jars…

I was kinda hoping someone here would have an idea

Cheers

Gary

Me neither :confused:

There have been plenty of times I also didn’t know anything and had to walk through experimenting and tweaking. Unfortunately that’s what we sometimes need to do. I’ve just found another example, that may help a little. Sorry I can’t provide more than that.

Mtom Message example.

Also, I can’t see any Content-Transfer-Encoding set up in your examples. Good luck.

Hi Andreas,

There have been plenty of times I also didn’t know anything and had to walk through experimenting and tweaking. Unfortunately that’s what we sometimes need to do. I’ve just found another example, that may help a little. Sorry I can’t provide more than that.

Sure absolutely, but there is no point in re-inventing the wheel and I generally can either solve myself or extrapolate from what I find on the internet for 99% of the challenges Ive faced in the last 20 odd years. The only hint I found that it was possible with CF was an old comment by Ray Camden on a Ben Nadel blog post where ACF supported multipart/related cfhttp posts… Ask Ben: Posting XML And File Data With ColdFusion And CFHttp

This problem, however, goes into that 1% where I take the time to ask the community if someone else has solved a similar challenge in the past. Its also a financial thing, either I can solve the problem in a timely manner (which doesnt seem to be the case) or I have to abandon it for a different approach all together.

Cheers,

Gary

1 Like

I have similar issues with some of my “code” talking nicely to Microsoft Teams.
the normal rest API graph versions in some cases break based upon what I set, no matter what I do.

What I ended up doing to make the file exactly formatted for teams includes building the underlying file with CFSAVECONTENT, and the CHR attributes. After the file is created, the next part of the script fires off a “put” action, which is nothing more than Cf Scheduled task every few minutes to run code against what should be a directory with ready to “put” messages.

The code ends up being something like <cfset mycrappycode ="chr(39) myargs chr47 moreargs -#formatargs#> cffile write Mycrappycode+args. then a scheduler goes off and reads and puts the file using curl.