| <!DOCTYPE html> |
| <!-- |
| | Generated by Apache Maven Doxia Site Renderer 1.7.4 at 2017-07-30 |
| | Rendered using Apache Maven Fluido Skin 1.6 |
| --> |
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
| <head> |
| <meta charset="UTF-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <meta name="Date-Revision-yyyymmdd" content="20170730" /> |
| <meta http-equiv="Content-Language" content="en" /> |
| <title>Apache Axis2 – Handling Binary data with Axis2 (MTOM/SwA)</title> |
| <link rel="stylesheet" href="../css/apache-maven-fluido-1.6.min.css" /> |
| <link rel="stylesheet" href="../css/site.css" /> |
| <link rel="stylesheet" href="../css/print.css" media="print" /> |
| <script type="text/javascript" src="../js/apache-maven-fluido-1.6.min.js"></script> |
| <meta http-equiv="content-type" content="" /> </head> |
| <body class="topBarDisabled"> |
| <div class="container-fluid"> |
| <div id="banner"> |
| <div class="pull-left"><a href="http://www.apache.org/" id="bannerLeft"><img src="http://www.apache.org/images/asf_logo_wide.png" alt="Apache Axis2"/></a></div> |
| <div class="pull-right"><a href=".././" id="bannerRight"><img src="../images/axis.jpg" /></a></div> |
| <div class="clear"><hr/></div> |
| </div> |
| |
| <div id="breadcrumbs"> |
| <ul class="breadcrumb"> |
| <li id="publishDate">Last Published: 2017-07-30<span class="divider">|</span> |
| </li> |
| <li id="projectVersion">Version: 1.7.6<span class="divider">|</span></li> |
| <li class=""><a href="http://www.apache.org" class="externalLink" title="Apache">Apache</a><span class="divider">/</span></li> |
| <li class=""><a href="../index.html" title="Axis2/Java">Axis2/Java</a><span class="divider">/</span></li> |
| <li class="active ">Handling Binary data with Axis2 (MTOM/SwA)</li> |
| </ul> |
| </div> |
| <div class="row-fluid"> |
| <div id="leftColumn" class="span2"> |
| <div class="well sidebar-nav"> |
| <ul class="nav nav-list"> |
| <li class="nav-header">Axis2/Java</li> |
| <li><a href="../index.html" title="Home"><span class="none"></span>Home</a> </li> |
| <li><a href="../download.html" title="Downloads"><span class="none"></span>Downloads</a> </li> |
| <li><a href="javascript:void(0)" title="Release Notes"><span class="icon-chevron-down"></span>Release Notes</a> |
| <ul class="nav nav-list"> |
| <li><a href="../release-notes/1.6.1.html" title="1.6.1"><span class="none"></span>1.6.1</a> </li> |
| <li><a href="../release-notes/1.6.2.html" title="1.6.2"><span class="none"></span>1.6.2</a> </li> |
| <li><a href="../release-notes/1.6.3.html" title="1.6.3"><span class="none"></span>1.6.3</a> </li> |
| <li><a href="../release-notes/1.6.4.html" title="1.6.4"><span class="none"></span>1.6.4</a> </li> |
| <li><a href="../release-notes/1.7.0.html" title="1.7.0"><span class="none"></span>1.7.0</a> </li> |
| <li><a href="../release-notes/1.7.1.html" title="1.7.1"><span class="none"></span>1.7.1</a> </li> |
| <li><a href="../release-notes/1.7.2.html" title="1.7.2"><span class="none"></span>1.7.2</a> </li> |
| <li><a href="../release-notes/1.7.3.html" title="1.7.3"><span class="none"></span>1.7.3</a> </li> |
| <li><a href="../release-notes/1.7.4.html" title="1.7.4"><span class="none"></span>1.7.4</a> </li> |
| <li><a href="../release-notes/1.7.5.html" title="1.7.5"><span class="none"></span>1.7.5</a> </li> |
| <li><a href="../release-notes/1.7.6.html" title="1.7.6"><span class="none"></span>1.7.6</a> </li> |
| </ul> |
| </li> |
| <li><a href="../modules/index.html" title="Modules"><span class="none"></span>Modules</a> </li> |
| <li><a href="../tools/index.html" title="Tools"><span class="none"></span>Tools</a> </li> |
| <li class="nav-header">Documentation</li> |
| <li><a href="../docs/toc.html" title="Table of Contents"><span class="none"></span>Table of Contents</a> </li> |
| <li><a href="../docs/installationguide.html" title="Installation Guide"><span class="none"></span>Installation Guide</a> </li> |
| <li><a href="../docs/quickstartguide.html" title="QuickStart Guide"><span class="none"></span>QuickStart Guide</a> </li> |
| <li><a href="../docs/userguide.html" title="User Guide"><span class="none"></span>User Guide</a> </li> |
| <li><a href="../docs/jaxws-guide.html" title="JAXWS Guide"><span class="none"></span>JAXWS Guide</a> </li> |
| <li><a href="../docs/pojoguide.html" title="POJO Guide"><span class="none"></span>POJO Guide</a> </li> |
| <li><a href="../docs/spring.html" title="Spring Guide"><span class="none"></span>Spring Guide</a> </li> |
| <li><a href="../docs/webadminguide.html" title="Web Administrator's Guide"><span class="none"></span>Web Administrator's Guide</a> </li> |
| <li><a href="../docs/migration.html" title="Migration Guide (from Axis1)"><span class="none"></span>Migration Guide (from Axis1)</a> </li> |
| <li class="nav-header">Resources</li> |
| <li><a href="../faq.html" title="FAQ"><span class="none"></span>FAQ</a> </li> |
| <li><a href="../articles.html" title="Articles"><span class="none"></span>Articles</a> </li> |
| <li><a href="http://wiki.apache.org/ws/FrontPage/Axis2/" class="externalLink" title="Wiki"><span class="none"></span>Wiki</a> </li> |
| <li><a href="../refLib.html" title="Reference Library"><span class="none"></span>Reference Library</a> </li> |
| <li><a href="../apidocs/index.html" title="Online Java Docs"><span class="none"></span>Online Java Docs</a> </li> |
| <li class="nav-header">Get Involved</li> |
| <li><a href="../overview.html" title="Overview"><span class="none"></span>Overview</a> </li> |
| <li><a href="../svn.html" title="Checkout the Source"><span class="none"></span>Checkout the Source</a> </li> |
| <li><a href="../mail-lists.html" title="Mailing Lists"><span class="none"></span>Mailing Lists</a> </li> |
| <li><a href="../release-process.html" title="Release Process"><span class="none"></span>Release Process</a> </li> |
| <li><a href="../guidelines.html" title="Developer Guidelines"><span class="none"></span>Developer Guidelines</a> </li> |
| <li><a href="../siteHowTo.html" title="Build the Site"><span class="none"></span>Build the Site</a> </li> |
| <li class="nav-header">Project Information</li> |
| <li><a href="../team-list.html" title="Project Team"><span class="none"></span>Project Team</a> </li> |
| <li><a href="../issue-tracking.html" title="Issue Tracking"><span class="none"></span>Issue Tracking</a> </li> |
| <li><a href="http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/" class="externalLink" title="Source Code"><span class="none"></span>Source Code</a> </li> |
| <li><a href="../thanks.html" title="Acknowledgements"><span class="none"></span>Acknowledgements</a> </li> |
| <li class="nav-header">Apache</li> |
| <li><a href="http://www.apache.org/licenses/LICENSE-2.0.html" class="externalLink" title="License"><span class="none"></span>License</a> </li> |
| <li><a href="http://www.apache.org/foundation/sponsorship.html" class="externalLink" title="Sponsorship"><span class="none"></span>Sponsorship</a> </li> |
| <li><a href="http://www.apache.org/foundation/thanks.html" class="externalLink" title="Thanks"><span class="none"></span>Thanks</a> </li> |
| <li><a href="http://www.apache.org/security/" class="externalLink" title="Security"><span class="none"></span>Security</a> </li> |
| </ul> |
| <hr /> |
| <div id="poweredBy"> |
| <div class="clear"></div> |
| <div class="clear"></div> |
| <div class="clear"></div> |
| <div class="clear"></div> |
| <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="../images/logos/maven-feather.png" /></a> |
| </div> |
| </div> |
| </div> |
| <div id="bodyColumn" class="span10" > |
| <html> |
| |
| |
| <h1>Handling Binary Data with Axis2 (MTOM/SwA)</h1> |
| |
| |
| <p>This document describes how to use the Axis2 functionality to send/receive |
| binary data with SOAP.</p> |
| |
| |
| <div class="section"> |
| <h2><a name="Content"></a>Content</h2> |
| |
| <ul> |
| |
| <li><a href="#a1">Introduction</a> |
| |
| <ul> |
| |
| <li><a href="#a11">Where Does MTOM Come In?</a></li> |
| </ul> |
| </li> |
| |
| <li><a href="#a2">MTOM with Axis2 </a> |
| |
| <ul> |
| |
| <li><a href="#a21">Programming Model</a></li> |
| |
| <li><a href="#a22">Enabling MTOM Optimization at Client Side</a></li> |
| |
| <li><a href="#a23">Enabling MTOM Optimization at Server Side</a></li> |
| |
| <li><a href="#a24">Accessing Received Binary Data (Sample Code) </a> |
| |
| <ul> |
| |
| <li><a href="#a241">Service</a></li> |
| |
| <li><a href="#a242">Client</a></li> |
| </ul> |
| </li> |
| |
| <li><a href="#a25">MTOM Databinding</a> |
| |
| <ul> |
| |
| <li><a href="#a251">Using ADB</a></li> |
| |
| </ul> |
| </li> |
| </ul> |
| </li> |
| |
| <li><a href="#a3">SOAP with Attachments with Axis2</a> |
| |
| <ul> |
| |
| <li><a href="#a31">Sending SwA Type Attachments</a></li> |
| |
| <li><a href="#a32">Receiving SwA Type Attachments</a></li> |
| |
| <li><a href="#a33">MTOM Backward Compatibility with SwA</a></li> |
| </ul> |
| </li> |
| |
| <li><a href="#a4">Advanced Topics </a> |
| |
| <ul> |
| |
| <li><a href="#a41">File Caching for Attachments</a></li> |
| </ul> |
| </li> |
| </ul> |
| <a name="a1"></a> |
| |
| |
| <div class="section"> |
| <h2><a name="Introduction"></a>Introduction</h2> |
| |
| |
| <p>Despite the flexibility, interoperability, and global acceptance of XML, |
| there are times when serializing data into XML does not make sense. Web |
| services users may want to transmit binary attachments of various sorts like |
| images, drawings, XML docs, etc., together with a SOAP message. Such data is |
| often in a particular binary format.<br /> |
| </p> |
| |
| |
| <p>Traditionally, two techniques have been used in dealing with opaque data |
| in XML;</p> |
| |
| <ol style="list-style-type: decimal"> |
| |
| <li><b>"By value"</b></li> |
| |
| |
| <blockquote> |
| |
| <p>Sending binary data by value is achieved by embedding opaque data (of |
| course after some form of encoding) as an element or attribute content of |
| the XML component of data. The main advantage of this technique is that |
| it gives applications the ability to process and describe data, based |
| only on the XML component of the data.</p> |
| |
| |
| <p>XML supports opaque data as content through the use of either base64 |
| or hexadecimal text encoding. Both techniques bloat the size of the data. |
| For UTF-8 underlying text encoding, base64 encoding increases the size of |
| the binary data by a factor of 1.33x of the original size, while |
| hexadecimal encoding expands data by a factor of 2x. The above factors |
| will be doubled if UTF-16 text encoding is used. Also of concern is the |
| overhead in processing costs (both real and perceived) for these formats, |
| especially when decoding back into raw binary.</p> |
| </blockquote> |
| |
| <li><b>"By reference"</b> |
| |
| |
| <blockquote> |
| |
| <p>Sending binary data by reference is achieved by attaching pure |
| binary data as external unparsed general entities outside the XML |
| document and then embedding reference URIs to those entities as |
| elements or attribute values. This prevents the unnecessary bloating of |
| data and wasting of processing power. The primary obstacle for using |
| these unparsed entities is their heavy reliance on DTDs, which impedes |
| modularity as well as the use of XML namespaces.</p> |
| |
| <p>There were several specifications introduced in the Web services |
| world to deal with this binary attachment problem using the "by |
| reference" technique. <a class="externalLink" href="http://www.w3.org/TR/SOAP-attachments">SOAP with Attachments</a> |
| is one such example. Since SOAP prohibits document type declarations |
| (DTD) in messages, this leads to the problem of not representing data |
| as part of the message infoset, therefore creating two data models. |
| This scenario is like sending attachments with an e-mail message. Even |
| though those attachments are related to the message content they are |
| not inside the message. This causes the technologies that process and |
| describe the data based on the XML component of the data to |
| malfunction. One example is WS-Security.</p> |
| </blockquote> |
| </li> |
| </ol> |
| <a name="a11"></a> |
| |
| |
| <div class="section"> |
| <h3><a name="Where_Does_MTOM_Come_In"></a>Where Does MTOM Come In?</h3> |
| |
| |
| <p><a class="externalLink" href="http://www.w3.org/TR/2004/PR-soap12-mtom-20041116/">MTOM (SOAP |
| Message Transmission Optimization Mechanism)</a> is another specification |
| that focuses on solving the "Attachments" problem. MTOM tries to leverage the |
| advantages of the above two techniques by trying to merge the two techniques. |
| MTOM is actually a "by reference" method. The wire format of a MTOM optimized |
| message is the same as the SOAP with Attachments message, which also makes it |
| backward compatible with SwA endpoints. The most notable feature of MTOM is |
| the use of the XOP:Include element, which is defined in the <a class="externalLink" href="http://www.w3.org/TR/2004/PR-xop10-20041116/">XML Binary Optimized |
| Packaging (XOP)</a> specification to reference the binary attachments |
| (external unparsed general entities) of the message. With the use of this |
| exclusive element, the attached binary content logically becomes inline (by |
| value) with the SOAP document even though it is actually attached separately. |
| This merges the two realms by making it possible to work only with one data |
| model. This allows the applications to process and describe by only looking |
| at the XML part, making the reliance on DTDs obsolete. On a lighter note, |
| MTOM has standardized the referencing mechanism of SwA. The following is an |
| extract from the <a class="externalLink" href="http://www.w3.org/TR/2004/PR-xop10-20041116/">XOP</a> specification.</p> |
| |
| |
| <p><i>At the conceptual level, this binary data can be thought of as being |
| base64-encoded in the XML Document. As this conceptual form might be needed |
| during some processing of the XML document (e.g., for signing the XML |
| document), it is necessary to have a one-to-one correspondence between XML |
| Infosets and XOP Packages. Therefore, the conceptual representation of such |
| binary data is as if it were base64-encoded, using the canonical lexical form |
| of the XML Schema base64Binary datatype (see <a href="#XMLSchemaP2">[XML |
| Schema Part 2: Datatypes Second Edition] </a> <a class="externalLink" href="http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#base64Binary">3.2.16 |
| base64Binary</a>). In the reverse direction, XOP is capable of optimizing |
| only base64-encoded Infoset data that is in the canonical lexical |
| form.</i></p> |
| |
| |
| <p>Apache Axis2 supports <b>Base64 encoding</b>, <b>SOAP with |
| Attachments</b> and <b>MTOM (SOAP Message Transmission Optimization |
| Mechanism).</b></p> |
| <a name="a2"></a> |
| |
| </div> |
| <div class="section"> |
| <h2><a name="MTOM_with_Axis2"></a>MTOM with Axis2</h2> |
| <a name="a21"></a> |
| |
| |
| <div class="section"> |
| <h3><a name="Programming_Model"></a>Programming Model</h3> |
| |
| |
| <p>AXIOM is (and may be the first) Object Model that has the ability to hold |
| binary data. It has this ability as OMText can hold raw binary content in the |
| form of javax.activation.DataHandler. OMText has been chosen for this purpose |
| with two reasons. One is that XOP (MTOM) is capable of optimizing only |
| base64-encoded Infoset data that is in the canonical lexical form of XML |
| Schema base64Binary datatype. Other one is to preserve the infoset in both |
| the sender and receiver. (To store the binary content in the same kind of |
| object regardless of whether it is optimized or not).</p> |
| |
| |
| <p>MTOM allows to selectively encode portions of the message, which allows us |
| to send base64encoded data as well as externally attached raw binary data |
| referenced by the "XOP" element (optimized content) to be sent in a SOAP |
| message. You can specify whether an OMText node that contains raw binary data |
| or base64encoded binary data is qualified to be optimized at the time of |
| construction of that node or later. For optimum efficiency of MTOM, a user is |
| advised to send smaller binary attachments using base64encoding |
| (non-optimized) and larger attachments as optimized content.</p> |
| |
| |
| <p></p> |
| |
| <div> |
| <pre> OMElement imageElement = fac.createOMElement("image", omNs); |
| |
| // Creating the Data Handler for the file. Any implementation of |
| // javax.activation.DataSource interface can fit here. |
| javax.activation.DataHandler dataHandler = new javax.activation.DataHandler(new FileDataSource("SomeFile")); |
| |
| //create an OMText node with the above DataHandler and set optimized to true |
| OMText textData = <b>fac.createOMText(dataHandler, true);</b> |
| |
| imageElement.addChild(textData); |
| |
| //User can set optimized to false by using the following |
| //textData.doOptimize(false);</pre></div> |
| |
| |
| <p>Also, a user can create an optimizable binary content node using a base64 |
| encoded string, which contains encoded binary content, given with the MIME |
| type of the actual binary representation.</p> |
| |
| |
| <p></p> |
| |
| <div> |
| <pre> String base64String = "some_base64_encoded_string"; |
| OMText binaryNode =<b>fac.createOMText(base64String,"image/jpg",true);</b></pre></div> |
| |
| |
| <p>Axis2 uses javax.activation.DataHandler to handle the binary data. All the |
| optimized binary content nodes will be serialized as Base64 Strings if "MTOM |
| is not enabled". You can also create binary content nodes, which will not be |
| optimized at any case. They will be serialized and sent as Base64 Strings.</p> |
| |
| |
| <p></p> |
| |
| <div> |
| <pre> //create an OMText node with the above DataHandler and set "optimized" to false |
| //This data will be send as Base64 encoded string regardless of MTOM is enabled or not |
| javax.activation.DataHandler dataHandler = new javax.activation.DataHandler(new FileDataSource("SomeFile")); |
| OMText textData = fac.createOMText(dataHandler, <b>false</b>); |
| image.addChild(textData);</pre></div> |
| <a name="a22"></a> |
| |
| </div> |
| <div class="section"> |
| <h3><a name="Enabling_MTOM_Optimization_on_the_Client_Side"></a>Enabling MTOM Optimization on the Client Side</h3> |
| |
| |
| <p>In Options, set the "enableMTOM" property to True when sending |
| messages.</p> |
| |
| |
| <p></p> |
| |
| <div> |
| <pre> ServiceClient serviceClient = new ServiceClient (); |
| Options options = new Options(); |
| options.setTo(targetEPR); |
| <b>options.setProperty(Constants.Configuration.ENABLE_MTOM, Constants.VALUE_TRUE);</b> |
| serviceClient .setOptions(options);</pre></div> |
| |
| |
| <p>When this property is set to True, any SOAP envelope, regardless of |
| whether it contains optimizable content or not, will be serialized as an MTOM |
| optimized MIME message.</p> |
| |
| |
| <p>Axis2 serializes all binary content nodes as Base64 encoded strings |
| regardless of whether they are qualified to be optimized or not</p> |
| |
| <ul> |
| |
| <li>if the "enableMTOM" property is set to False.</li> |
| |
| <li>if the envelope contains any element information items of the name |
| xop:Include (see <a href="#XOP">[XML-binary Optimized Packaging] </a><a class="externalLink" href="http://www.w3.org/TR/2005/REC-xop10-20050125/#xop_infosets">3. XOP |
| Infosets Constructs </a>).</li> |
| </ul> |
| |
| |
| <p>The user does <b>not</b> have to specify anything in order for |
| Axis2 to receive MTOM optimised messages. Axis2 will automatically identify |
| and de-serialize accordingly, as and when an MTOM message arrives.</p> |
| <a name="a23"></a> |
| |
| </div> |
| <div class="section"> |
| <h3><a name="Enabling_MTOM_Optimization_on_the_Server_Side"></a>Enabling MTOM Optimization on the Server Side</h3> |
| |
| |
| <p>The Axis 2 server automatically identifies incoming MTOM optimized |
| messages based on the content-type and de-serializes them accordingly. The |
| user can enableMTOM on the server side for outgoing messages,</p> |
| |
| |
| <blockquote> |
| |
| <p>To enableMTOM globally for all services, users can set the "enableMTOM" |
| parameter to True in the Axis2.xml. When it is set, all outgoing messages |
| will be serialized and sent as MTOM optimized MIME messages. If it is not |
| set, all the binary data in the binary content nodes will be serialized as |
| Base64 encoded strings. This configuration can be overriden in services.xml |
| on the basis of per service and per operation.</p> |
| </blockquote> |
| |
| <div> |
| <pre><parameter name="enableMTOM">true</parameter></pre></div> |
| |
| |
| <p>You must restart the server after setting this parameter.</p> |
| <a name="a24"></a> |
| |
| </div> |
| <div class="section"> |
| <h3><a name="Accessing_Received_Binary_Data_Sample_Code"></a>Accessing Received Binary Data (Sample Code)</h3> |
| <a name="a241"></a> |
| |
| <ul> |
| |
| <li><b>Service</b></li> |
| </ul> |
| |
| |
| <p></p> |
| |
| <div> |
| <pre>public class MTOMService { |
| public void uploadFileUsingMTOM(OMElement element) throws Exception { |
| |
| <b>OMText binaryNode = (OMText) (element.getFirstElement()).getFirstOMChild(); |
| DataHandler actualDH; |
| actualDH = (DataHandler) binaryNode.getDataHandler();</b> |
| |
| ... <i>Do whatever you need with the DataHandler</i> ... |
| } |
| }</pre></div> |
| <a name="a242"></a> |
| |
| <ul> |
| |
| <li><b>Client</b></li> |
| </ul> |
| |
| |
| <p></p> |
| |
| <div> |
| <pre> ServiceClient sender = new ServiceClient(); |
| Options options = new Options(); |
| options.setTo(targetEPR); |
| // enabling MTOM |
| <b>options.set(Constants.Configuration.ENABLE_MTOM, Constants.VALUE_TRUE);</b> |
| ............ |
| |
| OMElement result = sender.sendReceive(payload); |
| OMElement ele = result.getFirstElement(); |
| OMText binaryNode = (OMText) ele.getFirstOMChild(); |
| |
| // Retrieving the DataHandler & then do whatever the processing to the data |
| DataHandler actualDH; |
| actualDH = binaryNode.getDataHandler(); |
| .............</pre></div> |
| <a name="a25"></a> |
| |
| </div> |
| <div class="section"> |
| <h3><a name="MTOM_Databinding"></a>MTOM Databinding</h3> |
| |
| |
| <p>You can define a binary element in the schema using the schema |
| type="xsd:base64Binary". Having an element with the type "xsd:base64Binary" |
| is enough for the Axis2 code generators to identify possible MTOM |
| attachments, and to generate code accordingly.</p> |
| |
| |
| <p>Going a little further, you can use the xmime schema |
| (http://www.w3.org/2005/05/xmlmime) to describe the binary content more |
| precisely. With the xmime schema, you can indicate the type of content in the |
| element at runtime using an MTOM attribute extension xmime:contentType. |
| Furthermore, you can identify what type of data might be expected in the |
| element using the xmime:expectedContentType. Putting it all together, our |
| example element becomes:</p> |
| |
| <div> |
| <pre> <element name="MyBinaryData" xmime:expectedContentTypes='image/jpeg' > |
| <complexType> |
| <simpleContent> |
| <extension base="base64Binary" > |
| |
| <attribute ref="xmime:contentType" use="required"/> |
| </extension> |
| </simpleContent> |
| </complexType> |
| </element></pre></div> |
| |
| <p>You can also use the xmime:base64Binary type to express the above |
| mentioned data much clearly.</p> |
| |
| <div> |
| <pre> <element name="MyBinaryData" xmime:expectedContentTypes='image/jpeg' type="xmime:base64Binary"/></pre></div> |
| <a name="a251"></a> |
| |
| </div> |
| <div class="section"> |
| <h3><a name="MTOM_Databinding_Using_ADB"></a>MTOM Databinding Using ADB</h3> |
| |
| |
| <p>Let's define a full, validated doc/lit style WSDL that uses the xmime |
| schema, has a service that receives a file, and saves it in the server using |
| the given path.</p> |
| |
| <div> |
| <pre><wsdl:definitions xmlns:tns="http://ws.apache.org/axis2/mtomsample/" |
| xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" |
| xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" |
| xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" |
| xmlns:xmime="http://www.w3.org/2005/05/xmlmime" |
| xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" |
| xmlns:xsd="http://www.w3.org/2001/XMLSchema" |
| xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" |
| xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" |
| xmlns="http://schemas.xmlsoap.org/wsdl/" |
| targetNamespace="http://ws.apache.org/axis2/mtomsample/"> |
| |
| <wsdl:types> |
| <xsd:schema xmlns="http://schemas.xmlsoap.org/wsdl/" |
| attributeFormDefault="qualified" elementFormDefault="qualified" |
| targetNamespace="http://ws.apache.org/axis2/mtomsample/"> |
| |
| <xsd:import namespace="http://www.w3.org/2005/05/xmlmime" |
| schemaLocation="http://www.w3.org/2005/05/xmlmime" /> |
| <xsd:complexType name="AttachmentType"> |
| <xsd:sequence> |
| <xsd:element minOccurs="0" name="fileName" |
| type="xsd:string" /> |
| <xsd:element minOccurs="0" name="binaryData" |
| type="xmime:base64Binary" /> |
| </xsd:sequence> |
| </xsd:complexType> |
| <xsd:element name="AttachmentRequest" type="tns:AttachmentType" /> |
| <xsd:element name="AttachmentResponse" type="xsd:string" /> |
| </xsd:schema> |
| </wsdl:types> |
| <wsdl:message name="AttachmentRequest"> |
| <wsdl:part name="part1" element="tns:AttachmentRequest" /> |
| </wsdl:message> |
| <wsdl:message name="AttachmentResponse"> |
| <wsdl:part name="part1" element="tns:AttachmentResponse" /> |
| </wsdl:message> |
| <wsdl:portType name="MTOMServicePortType"> |
| <wsdl:operation name="attachment"> |
| <wsdl:input message="tns:AttachmentRequest" |
| wsaw:Action="attachment" /> |
| <wsdl:output message="tns:AttachmentResponse" |
| wsaw:Action="http://schemas.xmlsoap.org/wsdl/MTOMServicePortType/AttachmentResponse" /> |
| </wsdl:operation> |
| </wsdl:portType> |
| <wsdl:binding name="MTOMServiceSOAP11Binding" |
| type="tns:MTOMServicePortType"> |
| <soap:binding transport="http://schemas.xmlsoap.org/soap/http" |
| style="document" /> |
| <wsdl:operation name="attachment"> |
| <soap:operation soapAction="attachment" style="document" /> |
| <wsdl:input> |
| <soap:body use="literal" /> |
| </wsdl:input> |
| <wsdl:output> |
| <soap:body use="literal" /> |
| </wsdl:output> |
| </wsdl:operation> |
| </wsdl:binding> |
| <wsdl:binding name="MTOMServiceSOAP12Binding" |
| type="tns:MTOMServicePortType"> |
| <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" |
| style="document" /> |
| <wsdl:operation name="attachment"> |
| <soap12:operation soapAction="attachment" style="document" /> |
| <wsdl:input> |
| <soap12:body use="literal" /> |
| </wsdl:input> |
| <wsdl:output> |
| <soap12:body use="literal" /> |
| </wsdl:output> |
| </wsdl:operation> |
| </wsdl:binding> |
| <wsdl:service name="MTOMSample"> |
| <wsdl:port name="MTOMSampleSOAP11port_http" |
| binding="tns:MTOMServiceSOAP11Binding"> |
| <soap:address |
| location="http://localhost:8080/axis2/services/MTOMSample" /> |
| </wsdl:port> |
| <wsdl:port name="MTOMSampleSOAP12port_http" |
| binding="tns:MTOMServiceSOAP12Binding"> |
| <soap12:address |
| location="http://localhost:8080/axis2/services/MTOMSample" /> |
| </wsdl:port> |
| </wsdl:service> |
| </wsdl:definitions></pre></div> |
| |
| <p>The important point here is we import http://www.w3.org/2005/05/xmlmime |
| and define the element 'binaryData' that utilizes MTOM.</p> |
| |
| |
| <p>The next step is using the Axis2 tool 'WSDL2Java' to generate Java source |
| files from this WSDL. See the 'Code Generator Tool' guide for more |
| information. Here, we define an Ant task that chooses ADB (Axis2 Data |
| Binding) as the databinding implementation. The name we list for the WSDL |
| above is MTOMSample.wsdl, and we define our package name for our generated |
| source files to 'sample.mtom.service' . Our Ant task for this example is:</p> |
| |
| <div> |
| <pre> |
| <target name="generate.service"> |
| <java classname="org.apache.axis2.wsdl.WSDL2Java"> |
| <arg value="-uri" /> |
| <arg value="${basedir}/resources/MTOMSample.wsdl" /> |
| <arg value="-ss" /> |
| <arg value="-sd" /> |
| <arg value="-g"/> |
| <arg value="-p" /> |
| <arg value="sample.mtom.service" /> |
| <arg value="-o" /> |
| <arg value="${service.dir}" /> |
| <classpath refid="class.path" /> |
| </java> |
| </target></pre></div> |
| |
| <p>Now we are ready to code. Let's edit |
| output/src/sample/mtom/service/MTOMSampleSkeleton.java and fill in the |
| business logic. Here is an example:</p> |
| |
| <div> |
| <pre> public org.apache.ws.axis2.mtomsample.AttachmentResponse attachment( |
| org.apache.ws.axis2.mtomsample.AttachmentRequest param0) throws Exception |
| { |
| AttachmentType attachmentRequest = param0.getAttachmentRequest(); |
| Base64Binary binaryData = attachmentRequest.getBinaryData(); |
| DataHandler dataHandler = binaryData.getBase64Binary(); |
| File file = new File( |
| attachmentRequest.getFileName()); |
| FileOutputStream fileOutputStream = new FileOutputStream(file); |
| dataHandler.writeTo(fileOutputStream); |
| fileOutputStream.flush(); |
| fileOutputStream.close(); |
| |
| AttachmentResponse response = new AttachmentResponse(); |
| response.setAttachmentResponse("File saved succesfully."); |
| return response; |
| }</pre></div> |
| |
| <p>The code above receives a file and writes it to the disk using the given |
| file name. It returns a message once it is successful. Now let's define the |
| client:</p> |
| |
| <div> |
| <pre> public static void transferFile(File file, String destination) |
| throws RemoteException { |
| MTOMSampleStub serviceStub = new MTOMSampleStub(); |
| |
| // Enable MTOM in the client side |
| serviceStub._getServiceClient().getOptions().setProperty( |
| Constants.Configuration.ENABLE_MTOM, Constants.VALUE_TRUE); |
| //Increase the time out when sending large attachments |
| serviceStub._getServiceClient().getOptions().setTimeOutInMilliSeconds(10000); |
| |
| // Populating the code generated beans |
| AttachmentRequest attachmentRequest = new AttachmentRequest(); |
| AttachmentType attachmentType = new AttachmentType(); |
| Base64Binary base64Binary = new Base64Binary(); |
| |
| // Creating a javax.activation.FileDataSource from the input file. |
| FileDataSource fileDataSource = new FileDataSource(file); |
| |
| // Create a dataHandler using the fileDataSource. Any implementation of |
| // javax.activation.DataSource interface can fit here. |
| DataHandler dataHandler = new DataHandler(fileDataSource); |
| base64Binary.setBase64Binary(dataHandler); |
| base64Binary.setContentType(dataHandler.getContentType()); |
| attachmentType.setBinaryData(base64Binary); |
| attachmentType.setFileName(destination); |
| attachmentRequest.setAttachmentRequest(attachmentType); |
| |
| AttachmentResponse response = serviceStub.attachment(attachmentRequest); |
| System.out.println(response.getAttachmentResponse()); |
| }</pre></div> |
| |
| <p>The last step is to create an AAR with our Skeleton and the services.xml |
| and then deploy the service. You can find the completed sample in the Axis2 |
| standard binary distribution under the samples/mtom directory</p> |
| <a name="a252"></a> <a name="a3"></a> |
| |
| </div> |
| <div class="section"> |
| <h2><a name="SOAP_with_Attachments_SwA_with_Axis2"></a>SOAP with Attachments (SwA) with Axis2</h2> |
| <a name="a31"></a> |
| |
| |
| <div class="section"> |
| <h3><a name="Receiving_SwA_Type_Attachments"></a>Receiving SwA Type Attachments</h3> |
| |
| |
| <p>Axis2 automatically identifies SwA messages based on the content type. |
| Axis2 stores the references on the received attachment parts (MIME parts) in |
| the Message Context. Axis2 preserves the order of the received attachments |
| when storing them in the MessageContext. Users can access binary attachments |
| using the attachement API given in the Message Context using the content-id |
| of the mime part as the key. Care needs be taken to rip off the "cid" prefix |
| when content-id is taken from the "Href" attributes. Users can access the |
| message context from whithin a service implementation class using the |
| "setOperationContext()" method as shown in the following example.</p> |
| |
| |
| <p>Note: Axis2 supports content-id based referencing only. Axis2 does not |
| support Content Location based referencing of MIME parts.</p> |
| |
| <ul> |
| |
| <li><b>Sample service which accesses a received SwA type |
| attachment</b></li> |
| </ul> |
| |
| <div> |
| <pre>public class SwA { |
| public SwA() { |
| } |
| |
| public void uploadAttachment(OMElement omEle) throws AxisFault { |
| OMElement child = (OMElement) omEle.getFirstOMChild(); |
| OMAttribute attr = child.getAttribute(new QName("href")); |
| |
| //Content ID processing |
| String contentID = attr.getAttributeValue(); |
| contentID = contentID.trim(); |
| if (contentID.substring(0, 3).equalsIgnoreCase("cid")) { |
| contentID = contentID.substring(4); |
| } |
| |
| MessageContext msgCtx = MessageContext.getCurrentMessageContext(); |
| Attachments attachment = msgCtx.getAttachmentMap(); |
| DataHandler dataHandler = attachment.getDataHandler(contentID); |
| ........... |
| } |
| }</pre></div> |
| <a name="a32"></a> |
| |
| </div> |
| <div class="section"> |
| <h3><a name="Sending_SwA_Type_Attachments"></a>Sending SwA Type Attachments</h3> |
| |
| |
| <p>The user needs to set the "enableSwA" property to True in order to be able |
| to send SwA messages. The Axis2 user is <b>not</b> expected to |
| enable MTOM and SwA together. In such a situation, MTOM will get priority |
| over SwA.</p> |
| |
| |
| <p>This can be set using the axis2.xml as follows.</p> |
| |
| <div> |
| <pre> |
| <parameter name="enableSwA">true</parameter></pre></div> |
| |
| <p>"enableSwA" can also be set using the client side Options as follows</p> |
| |
| <div> |
| <pre> |
| options.setProperty(Constants.Configuration.ENABLE_SwA, Constants.VALUE_TRUE);</pre></div> |
| |
| <p>Users are expected to use the attachment API provided in the |
| MessageContext to specify the binary attachments needed to be attached to the |
| outgoing message as SwA type attachments. Client side SwA capability can be |
| used only with the OperationClient api, since the user needs the ability to |
| access the MessageContext.</p> |
| |
| <ul> |
| |
| <li><b>Sample client which sends a message with SwA type |
| attachments</b></li> |
| </ul> |
| |
| <div> |
| <pre> public void uploadFileUsingSwA(String fileName) throws Exception { |
| |
| Options options = new Options(); |
| options.setTo(targetEPR); |
| options.setProperty(Constants.Configuration.ENABLE_SWA, Constants.VALUE_TRUE); |
| options.setTransportInProtocol(Constants.TRANSPORT_HTTP); |
| options.setSoapVersionURI(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI); |
| options.setTo(targetEPR); |
| |
| ServiceClient sender = new ServiceClient(null,null); |
| sender.setOptions(options); |
| OperationClient mepClient = sender.createClient(ServiceClient.ANON_OUT_IN_OP); |
| |
| MessageContext mc = new MessageContext(); |
| mc.setEnvelope(createEnvelope()); |
| FileDataSource fileDataSource = new FileDataSource("test-resources/mtom/test.jpg"); |
| DataHandler dataHandler = new DataHandler(fileDataSource); |
| mc.addAttachment("FirstAttachment",dataHandler); |
| |
| mepClient.addMessageContext(mc); |
| mepClient.execute(true); |
| }</pre></div> |
| <a name="a33"></a> |
| |
| </div> |
| <div class="section"> |
| <h3><a name="MTOM_Backward_Compatibility_with_SwA"></a>MTOM Backward Compatibility with SwA</h3> |
| |
| |
| <p>MTOM specification is designed to be backward compatible with the SOAP |
| with Attachments specification. Even though the representation is different, |
| both technologies have the same wire format. We can safely assume that any |
| SOAP with Attachments endpoint can accept MTOM optimized messages and treat |
| them as SOAP with Attachment messages - any MTOM optimized message is a valid |
| SwA message.</p> |
| |
| |
| <p>Note : Above backword compatibility was succesfully tested against Axis |
| 1.x</p> |
| |
| <ul> |
| |
| <li><b>A sample SwA message from Axis 1.x</b></li> |
| </ul> |
| |
| <div> |
| <pre>Content-Type: multipart/related; type="text/xml"; |
| start="<9D645C8EBB837CE54ABD027A3659535D>"; |
| boundary="----=_Part_0_1977511.1123163571138" |
| |
| ------=_Part_0_1977511.1123163571138 |
| Content-Type: text/xml; charset=UTF-8 |
| Content-Transfer-Encoding: binary |
| Content-Id: <9D645C8EBB837CE54ABD027A3659535D> |
| |
| <?xml version="1.0" encoding="UTF-8"?> |
| <soapenv:Envelope xmlns:soapenv="...."....> |
| ........ |
| <source href="cid:3936AE19FBED55AE4620B81C73BDD76E" xmlns="/> |
| |
| ........ |
| </soapenv:Envelope> |
| ------=_Part_0_1977511.1123163571138 |
| Content-Type: text/plain |
| Content-Transfer-Encoding: binary |
| Content-Id: <3936AE19FBED55AE4620B81C73BDD76E> |
| |
| <i>Binary Data.....</i> |
| ------=_Part_0_1977511.1123163571138--</pre></div> |
| |
| <ul> |
| |
| <li><b>Corresponding MTOM message from Axis2</b></li> |
| </ul> |
| |
| <div> |
| <pre>Content-Type: multipart/related; boundary=MIMEBoundary4A7AE55984E7438034; |
| type="application/xop+xml"; start="<0.09BC7F4BE2E4D3EF1B@apache.org>"; |
| start-info="text/xml; charset=utf-8" |
| |
| --MIMEBoundary4A7AE55984E7438034 |
| content-type: application/xop+xml; charset=utf-8; type="application/soap+xml;" |
| content-transfer-encoding: binary |
| content-id: <0.09BC7F4BE2E4D3EF1B@apache.org> |
| |
| <?xml version='1.0' encoding='utf-8'?> |
| <soapenv:Envelope xmlns:soapenv="...."....> |
| ........ |
| <xop:Include href="cid:1.A91D6D2E3D7AC4D580@apache.org" |
| xmlns:xop="http://www.w3.org/2004/08/xop/include"> |
| </xop:Include> |
| ........ |
| |
| </soapenv:Envelope> |
| --MIMEBoundary4A7AE55984E7438034 |
| content-type: application/octet-stream |
| content-transfer-encoding: binary |
| content-id: <1.A91D6D2E3D7AC4D580@apache.org> |
| |
| <i>Binary Data.....</i> |
| --MIMEBoundary4A7AE55984E7438034--</pre></div> |
| <a name="a4"></a> |
| |
| </div> |
| <div class="section"> |
| <h2><a name="Advanced_Topics"></a>Advanced Topics</h2> |
| <a name="a41"></a> |
| |
| |
| <div class="section"> |
| <h3><a name="File_Caching_for_Attachments"></a>File Caching for Attachments</h3> |
| |
| |
| <p>Axis2 comes handy with a file caching mechanism for incoming attachments, |
| which gives Axis2 the ability to handle very large attachments without |
| buffering them in the memory at any time. Axis2 file caching streams the |
| incoming MIME parts directly into the files, after reading the MIME part |
| headers.</p> |
| |
| |
| <p>Also, a user can specify a size threshold for the File caching (in bytes). |
| When this threshold value is specified, only the attachments whose size is |
| bigger than the threshold value will get cached in the files. Smaller |
| attachments will remain in the memory.</p> |
| |
| |
| <p>Note : It is a must to specify a directory to temporarily store the |
| attachments. Also care should be taken to <b>clean that |
| directory</b> from time to time.</p> |
| |
| |
| <p>The following parameters need to be set in Axis2.xml in order to enable |
| file caching.</p> |
| |
| <div> |
| <pre><axisconfig name="AxisJava2.0"> |
| |
| <!-- ================================================= --> |
| <!-- Parameters --> |
| <!-- ================================================= --> |
| <parameter name="cacheAttachments">true</parameter> |
| <parameter name="attachmentDIR"><i>temp directory</i></parameter> |
| |
| <parameter name="sizeThreshold"><i>4000</i></parameter> |
| ......... |
| ......... |
| </axisconfig></pre></div> |
| |
| <p>Enabling file caching for client side receiving can be done for the by |
| setting the Options as follows.</p> |
| |
| <div> |
| <pre>options.setProperty(Constants.Configuration.CACHE_ATTACHMENTS,Constants.VALUE_TRUE); |
| options.setProperty(Constants.Configuration.ATTACHMENT_TEMP_DIR,<i>TempDir</i>); |
| options.setProperty(Constants.Configuration.FILE_SIZE_THRESHOLD, <i>"4000"</i>);</pre></div> |
| </div> |
| </html> |
| </div> |
| </div> |
| </div> |
| <hr/> |
| <footer> |
| <div class="container-fluid"> |
| <div class="row-fluid"> |
| <p>Copyright ©2004–2017 |
| <a href="https://www.apache.org/">The Apache Software Foundation</a>. |
| All rights reserved.</p> |
| </div> |
| </div> |
| </footer> |
| </body> |
| </html> |