cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache CXF Documentation > MTOM Attachments with JAXB
Date Sat, 02 Oct 2010 18:55:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1810/9/1/_/styles/combined.css?spaceKey=CXF20DOC&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CXF20DOC/MTOM+Attachments+with+JAXB">MTOM
Attachments with JAXB</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~bimargulies@gmail.com">Benson
Margulies</a>
    </h4>
        <br/>
                         <h4>Changes (1)</h4>
                                 
    
<div id="page-diffs">
            <table class="diff" cellpadding="0" cellspacing="0">
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Note
the use of &#39;application/octet-stream&#39;. According to the standard, you should
be able to use any MIME type you like, in order to specify the actual content of the attachment.
However, due to a defect in the JAX-B reference implementation, this won&#39;t work. 
<br> <br></td></tr>
            <tr><td class="diff-unchanged" >h1. 2) Enable MTOM on your service
<br>If you&#39;ve used JAX-WS to publish your endpoint you can enable MTOM like
so: <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
        </table>
</div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <p><a href="http://www.w3.org/TR/soap12-mtom/" class="external-link" rel="nofollow">MTOM</a>
is a standard which allows your services to transfer binary data efficiently and conveniently.
Many frameworks have support for MTOM - Axis2, JAX-WS RI, JBoss WS, XFire, Microsoft's WCF,
and more.</p>

<p>If the binary is part of the XML document, it needs to be base64 encoded - taking
CPU time and increasing the payload size. When MTOM is enabled on a service, it takes binary
data which might normally be part of the XML document, and creates an attachment for it. </p>

<p>Enabling MTOM is a rather simple process. First, you must annotate your schema type
or POJO to let JAXB know that a particular field could be a candidate for MTOM optimization.
Second, you just tell CXF that you wish to enable MTOM.</p>

<p>This page tells you how to activate MTOM for JAXB. MTOM is also supported in Aegis.</p>

<h1><a name="MTOMAttachmentswithJAXB-1%29AnnotatingtheMessage"></a>1) Annotating
the Message</h1>

<h2><a name="MTOMAttachmentswithJAXB-1a%29ModifyingyourschemaforMTOM"></a>1a)
Modifying your schema for MTOM</h2>
<p>Lets say we have a Picture schema type like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
&lt;schema targetNamespace=<span class="code-quote">"http://pictures.com"</span>
  <span class="code-keyword">xmlns:xsd</span>=<span class="code-quote">"http://www.w3.org/2001/XMLSchema"</span>&gt;
  <span class="code-tag">&lt;element name=<span class="code-quote">"Picture"</span>&gt;</span>
    <span class="code-tag">&lt;complexType&gt;</span>
      <span class="code-tag">&lt;sequence&gt;</span>
        <span class="code-tag">&lt;element name=<span class="code-quote">"Title"</span>
type=<span class="code-quote">"xsd:string"</span>/&gt;</span>
        <span class="code-tag">&lt;element name=<span class="code-quote">"ImageData"</span>
type=<span class="code-quote">"xsd:base64Binary"</span>/&gt;</span>
      <span class="code-tag">&lt;/sequence&gt;</span>
    <span class="code-tag">&lt;/complexType&gt;</span>
  <span class="code-tag">&lt;/element&gt;</span>
<span class="code-tag">&lt;/schema&gt;</span>
</pre>
</div></div>
<p>In this case the ImageData element is something we would like to have transferred
as an attachment. To do this we just need to add an xmime:expectedContentTypes annotation:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
&lt;schema targetNamespace=<span class="code-quote">"http://pictures.com"</span>

  <span class="code-keyword">xmlns:xsd</span>=<span class="code-quote">"http://www.w3.org/2001/XMLSchema"</span>
  <span class="code-keyword">xmlns:xmime</span>=<span class="code-quote">"http://www.w3.org/2005/05/xmlmime"</span>&gt;
  <span class="code-tag">&lt;element name=<span class="code-quote">"Picture"</span>&gt;</span>
    <span class="code-tag">&lt;complexType&gt;</span>
      <span class="code-tag">&lt;sequence&gt;</span>
        <span class="code-tag">&lt;element name=<span class="code-quote">"Title"</span>
type=<span class="code-quote">"xsd:string"</span>/&gt;</span>
        &lt;element name=<span class="code-quote">"ImageData"</span> type=<span
class="code-quote">"xsd:base64Binary"</span>
           xmime:expectedContentTypes=<span class="code-quote">"application/octet-stream"</span>/&gt;
      <span class="code-tag">&lt;/sequence&gt;</span>
    <span class="code-tag">&lt;/complexType&gt;</span>
  <span class="code-tag">&lt;/element&gt;</span>
<span class="code-tag">&lt;/schema&gt;</span>
</pre>
</div></div>
<p>This tells JAXB (which WSDL2Java uses to generate POJOs for your service) that this
field could be of any content type. Instead of creating a byte[] array for the base64Binary
element, it will create a DataHandler instead which can be used to stream the data.</p>

<h2><a name="MTOMAttachmentswithJAXB-1b%29AnnotationyourJAXBbeanstoenableMTOM"></a>1b)
Annotation your JAXB beans to enable MTOM</h2>
<p>If you're doing code first, you need to add an annotation to your POJO to tell JAXB
that the field is a candidate for MTOM optimization. Lets say we have a Picture class with
has Title and ImageData fields, then it might look like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@XmlType
<span class="code-keyword">public</span> class Picture {
  <span class="code-keyword">private</span> <span class="code-object">String</span>
title;

  @XmlMimeType(<span class="code-quote">"application/octet-stream"</span>)
  <span class="code-keyword">private</span> DataHandler imageData;

  <span class="code-keyword">public</span> <span class="code-object">String</span>
getTitle() { <span class="code-keyword">return</span> title; }
  <span class="code-keyword">public</span> void setTitle(<span class="code-object">String</span>
title) { <span class="code-keyword">this</span>.title = title; }

  <span class="code-keyword">public</span> DataHandler getImageData() { <span
class="code-keyword">return</span> imageData; }
  <span class="code-keyword">public</span> void setImageData(DataHandler imageData)
{ <span class="code-keyword">this</span>.imageData = imageData; }
}
</pre>
</div></div>

<p>Note the use of 'application/octet-stream'. According to the standard, you should
be able to use any MIME type you like, in order to specify the actual content of the attachment.
However, due to a defect in the JAX-B reference implementation, this won't work. </p>

<h1><a name="MTOMAttachmentswithJAXB-2%29EnableMTOMonyourservice"></a>2)
Enable MTOM on your service</h1>
<p>If you've used JAX-WS to publish your endpoint you can enable MTOM like so:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">import</span> javax.xml.ws.Endpoint;
<span class="code-keyword">import</span> javax.xml.ws.soap.SOAPBinding;

Endpoint ep = Endpoint.publish(<span class="code-quote">"http:<span class="code-comment">//localhost/myService"</span>,
<span class="code-keyword">new</span> MyService());
</span>SOAPBinding binding = (SOAPBinding) ep.getBinding();
binding.setMTOMEnabled(<span class="code-keyword">true</span>);
</pre>
</div></div>

<p>Or, if you used XML to publish your endpoint:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
&lt;beans xmlns=<span class="code-quote">"http://www.springframework.org/schema/beans"</span>
	<span class="code-keyword">xmlns:xsi</span>=<span class="code-quote">"http://www.w3.org/2001/XMLSchema-instance"</span>
	<span class="code-keyword">xmlns:jaxws</span>=<span class="code-quote">"http://cxf.apache.org/jaxws"</span>
	xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd"&gt;

  &lt;jaxws:endpoint 
    id=<span class="code-quote">"helloWorld"</span> 
    implementor=<span class="code-quote">"demo.spring.HelloWorldImpl"</span> 
    address=<span class="code-quote">"http://localhost/HelloWorld"</span>&gt;
    <span class="code-tag">&lt;jaxws:properties&gt;</span>
      <span class="code-tag">&lt;entry key=<span class="code-quote">"mtom-enabled"</span>
value=<span class="code-quote">"true"</span>/&gt;</span>
    <span class="code-tag">&lt;/jaxws:properties&gt;</span>
  <span class="code-tag">&lt;/jaxws:endpoint&gt;</span>

<span class="code-tag">&lt;/beans&gt;</span>
</pre>
</div></div>

<p>If you're using the simple frontend you can set the mtom-enabled property on your
ServerFactoryBean or ClientProxyFactoryBean:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
Map&lt;<span class="code-object">String</span>,<span class="code-object">Object</span>&gt;
props = <span class="code-keyword">new</span> HashMap&lt;<span class="code-object">String</span>,
<span class="code-object">Object</span>&gt;();
props.put(<span class="code-quote">"mtom-enabled"</span>, <span class="code-object">Boolean</span>.TRUE);
<span class="code-comment">// <span class="code-object">Boolean</span>.TRUE
or <span class="code-quote">"<span class="code-keyword">true</span>"</span>
will work as the property value here
</span>
ClientProxyFactoryBean pf = <span class="code-keyword">new</span> ClientProxyFactoryBean();
pf.setPropertyies(props);
....
YourClient client = (YourClient) pf.create();

ServerFactoryBean sf = <span class="code-keyword">new</span> ServerFactoryBean();
sf.setPropertyies(props);
...
sf.create();
</pre>
</div></div>

<p>Similarly, you can use the XML configuration:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
&lt;beans xmlns=<span class="code-quote">"http://www.springframework.org/schema/beans"</span>
	<span class="code-keyword">xmlns:xsi</span>=<span class="code-quote">"http://www.w3.org/2001/XMLSchema-instance"</span>
	<span class="code-keyword">xmlns:simple</span>=<span class="code-quote">"http://cxf.apache.org/simple"</span>
	xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/simple http://cxf.apache.org/schema/simple.xsd"&gt;

  &lt;simple:server
    id=<span class="code-quote">"helloWorld"</span> 
    serviceClass=<span class="code-quote">"demo.spring.HelloWorldImpl"</span>

    address=<span class="code-quote">"http://localhost/HelloWorld"</span>&gt;
    <span class="code-tag">&lt;simple:properties&gt;</span>
      <span class="code-tag">&lt;entry key=<span class="code-quote">"mtom-enabled"</span>
value=<span class="code-quote">"true"</span>/&gt;</span>
    <span class="code-tag">&lt;/simple:properties&gt;</span>
  <span class="code-tag">&lt;/simple:server&gt;</span>

  &lt;simple:client
    id=<span class="code-quote">"helloWorldClient"</span> 
    serviceClass=<span class="code-quote">"demo.spring.HelloWorldImpl"</span>

    address=<span class="code-quote">"http://localhost/HelloWorld"</span>&gt;
    <span class="code-tag">&lt;simple:properties&gt;</span>
      <span class="code-tag">&lt;entry key=<span class="code-quote">"mtom-enabled"</span>
value=<span class="code-quote">"true"</span>/&gt;</span>
    <span class="code-tag">&lt;/simple:properties&gt;</span>
  <span class="code-tag">&lt;/simple:client&gt;</span>

<span class="code-tag">&lt;/beans&gt;</span>
</pre>
</div></div>

<h1><a name="MTOMAttachmentswithJAXB-UsingDataHandlers"></a>Using DataHandlers</h1>
<p>Once you've got the above done, its time to start writing your logic. DataHandlers
are easy to use and create. To consume a DataHandler:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
Picture picture = ...;
DataHandler handler = picture.getImageData();
InputStream is = handler.getInputStream();
</pre>
</div></div>

<p>There are many ways to create DataHandlers. You can use a FileDataSource, ByteArrayDataSource,
or write your own DataSource:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
DataSource source = <span class="code-keyword">new</span> ByteArrayDataSource(<span
class="code-keyword">new</span> <span class="code-object">byte</span>[]
{...}, <span class="code-quote">"content/type"</span>);
DataSource source = <span class="code-keyword">new</span> FileDataSource(<span
class="code-keyword">new</span> File(<span class="code-quote">"my/file"</span>));

Picture picture = <span class="code-keyword">new</span> Picture();
picture.setImageData(<span class="code-keyword">new</span> DataHandler(source));
</pre>
</div></div>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/MTOM+Attachments+with+JAXB">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=51896&revisedVersion=9&originalVersion=8">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/MTOM+Attachments+with+JAXB?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message