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 > JAX-RS Data Bindings
Date Tue, 21 Dec 2010 22:28: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/JAX-RS+Data+Bindings">JAX-RS
Data Bindings</a></h2>
    <h4>Page  <b>added</b> by             <a href="https://cwiki.apache.org/confluence/display/~sergey_beryozkin">Sergey
Beryozkin</a>
    </h4>
         <br/>
    <div class="notificationGreySide">
         <span style="font-size:2em;font-weight:bold"> JAX-RS : Data Bindings </span>

<div>
<ul>
    <li><a href='#JAX-RSDataBindings-JAXBsupport'>JAXB support</a></li>
<ul>
    <li><a href='#JAX-RSDataBindings-ConfiguringJAXBprovider'>Configuring JAXB
provider</a></li>
</ul>
    <li><a href='#JAX-RSDataBindings-JSONsupport'>JSON support</a></li>
<ul>
    <li><a href='#JAX-RSDataBindings-ConfiguringJSONprovider'>Configuring JSON
provider</a></li>
    <li><a href='#JAX-RSDataBindings-DealingwithJSONarrayserializationissues'>Dealing
with JSON array serialization issues</a></li>
    <li><a href='#JAX-RSDataBindings-BadgerFishconvention'>BadgerFish convention</a></li>
    <li><a href='#JAX-RSDataBindings-WrappingandUnwrappingJSONsequences'>Wrapping
and Unwrapping JSON sequences</a></li>
</ul>
    <li><a href='#JAX-RSDataBindings-CommonJAXBandJSONconfiguration'>Common JAXB
and JSON configuration</a></li>
<ul>
    <li><a href='#JAX-RSDataBindings-AutomaticJAXBElementconversionduringserialization'>Automatic
JAXBElement conversion during serialization</a></li>
    <li><a href='#JAX-RSDataBindings-HandlingJAXBbeanswithoutXmlRootElementannotations'>Handling
JAXB beans without XmlRootElement annotations</a></li>
    <li><a href='#JAX-RSDataBindings-Handlingexplicitcollections'>Handling explicit
collections</a></li>
    <li><a href='#JAX-RSDataBindings-CustomizingJAXBXMLandJSONinputandoutput'>Customizing
JAXB XML and JSON input and output</a></li>
</ul>
    <li><a href='#JAX-RSDataBindings-Atom'>Atom</a></li>
    <li><a href='#JAX-RSDataBindings-AegisDataBinding'>Aegis Data Binding</a></li>
    <li><a href='#JAX-RSDataBindings-XMLBeans'>XMLBeans</a></li>
    <li><a href='#JAX-RSDataBindings-CXFDataBindings'>CXF DataBindings</a></li>
    <li><a href='#JAX-RSDataBindings-Schemavalidation'>Schema validation</a></li>
    <li><a href='#JAX-RSDataBindings-FastInfoset'>Fast Infoset</a></li>
</ul></div>

<h2><a name="JAX-RSDataBindings-JAXBsupport"></a>JAXB support</h2>

<p>The request and response can be marshalled and unmarshalled to/from Java object using
JAXB. </p>

<p>There's a number of ways to tell to the JAXB provider how objects can be serialized.
The simplest way is to mark a given type with @XmlRootElement annotation. </p>


<p>For example:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@XmlRootElement(name = <span class="code-quote">"Customer"</span>)
<span class="code-keyword">public</span> class Customer {
    <span class="code-keyword">private</span> <span class="code-object">String</span>
name;
    <span class="code-keyword">private</span> <span class="code-object">long</span>
id;

    <span class="code-keyword">public</span> Customer() {
    }

    <span class="code-keyword">public</span> void setName(<span class="code-object">String</span>
n) {
        name = n;
    }

    <span class="code-keyword">public</span> <span class="code-object">String</span>
getName() {
        <span class="code-keyword">return</span> name;
    }

    <span class="code-keyword">public</span> void setId(<span class="code-object">long</span>
i) {
        id = i;
    }

    <span class="code-keyword">public</span> <span class="code-object">long</span>
getId() {
        <span class="code-keyword">return</span> id;
    }
}
</pre>
</div></div>
<p>In the example below, the Customer object returned by getCustomer is marshaled using
JAXB data binding:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/customerservice/"</span>)
<span class="code-keyword">public</span> class CustomerService {
    @GET
    @Path(<span class="code-quote">"/customers/{customerId}/"</span>)
    <span class="code-keyword">public</span> Customer getCustomer(@PathParam(<span
class="code-quote">"customerId"</span>) <span class="code-object">String</span>
id) {
        ....
    }
}
</pre>
</div></div>
<p>The wire representation of Customer object is:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;Customer&gt;</span>
    <span class="code-tag">&lt;id&gt;</span>123<span class="code-tag">&lt;/id&gt;</span>
    <span class="code-tag">&lt;name&gt;</span>John<span class="code-tag">&lt;/name&gt;</span>
<span class="code-tag">&lt;/Customer&gt;</span>
</pre>
</div></div>

<p>The simplest way to work with the collections is to define a type representing a
collection. For example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@XmlRootElement(name = <span class="code-quote">"Customers"</span>)
<span class="code-keyword">public</span> class Customers {
    <span class="code-keyword">private</span> Collection&lt;Customer&gt;
customers;

    <span class="code-keyword">public</span> Collection&lt;Customer&gt;
getCustomer() {
        <span class="code-keyword">return</span> customers;
    }

    <span class="code-keyword">public</span> void setCustomer(Collection&lt;Customer&gt;
c) {
        <span class="code-keyword">this</span>.customers = c;
    }
}
@Path(<span class="code-quote">"/customerservice/"</span>)
<span class="code-keyword">public</span> class CustomerService {
    @GET
    @Path(<span class="code-quote">"/customers/"</span>)
    <span class="code-keyword">public</span> Customers getCustomers() {
        ....
    }
}
</pre>
</div></div>

<p>Alternatively to using @XmlRootElement and Collection wrappers, one can provide an
Object factory which will tell JAXB how to <br/>
marshal a given type (in case of Collections - its template type). Another option is to return/accept
a JAXBElement directly from/in <br/>
a given method.</p>

<p>Another option is to register one or more JAX-RS ContextResolver providers capable
of creating JAXBContexts for a number of different types. The default JAXBElementProvider
will check these resolvers first before attempting to create a JAXBContext on its own.   </p>

<p>Finally, JAXBProvider provides a support for serializing response types and deserializing
parameters of methods annotated with @XmlJavaTypeAdapter annotations.     </p>

<h3><a name="JAX-RSDataBindings-ConfiguringJAXBprovider"></a>Configuring
JAXB provider</h3>

<p>The default JAXB provider can be configured in a number of ways. For example, here's
how to set up marshall properties :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;beans <span class="code-keyword">xmlns:util</span>=<span
class="code-quote">"http://www.springframework.org/schema/util"</span>&gt;</span>
<span class="code-tag">&lt;bean id=<span class="code-quote">"jaxbProvider"</span>
class=<span class="code-quote">"org.apache.cxf.jaxrs.provider.JAXBElementProvider"</span>&gt;</span>
<span class="code-tag">&lt;property name=<span class="code-quote">"marshallerProperties"</span>
ref=<span class="code-quote">"propertiesMap"</span>/&gt;</span>
<span class="code-tag">&lt;/bean&gt;</span>
<span class="code-tag">&lt;util:map id=<span class="code-quote">"propertiesMap"</span>&gt;</span>
<span class="code-tag">&lt;entry key=<span class="code-quote">"jaxb.formatted.output"</span>&gt;</span>
   <span class="code-tag">&lt;value type=<span class="code-quote">"java.lang.Boolean"</span>&gt;</span>true<span
class="code-tag">&lt;/value&gt;</span>
<span class="code-tag">&lt;/entry&gt;</span>
<span class="code-tag">&lt;/util:map&gt;</span>
/<span class="code-tag">&lt;beans&gt;</span>
</pre>
</div></div>

<p>Individual marshal properties can be injected as simple properties. At the moment,
Marshaller.JAXB_SCHEMA_LOCATION can be injected as "schemaLocation" property. Schema validation
can be enabled and custom &#64;Consume and &#64;Produce media types can be injected,
see <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml"
class="external-link" rel="nofollow">this example</a> and "Customizing media types
for message body providers" and "Schema Validation Support" sections for more information.
</p>

<p>One issue which one may need to be aware of it is that an exception may occur during
the JAXB serialization process, after some content has already been processed and written
to the output stream. By default, the output goes directly to the output HTTP stream so if
an exception occurs midway through the process then the output will likely be malformed. If
you set 'enableBuffering' property to 'true' then a JAXB provider will write to the efficient
CXF CachedOutputStream instead and if an exception occurs then no text which has already been
written will make it to the outside world and it will be only this exception that will be
reported to the client.  </p>

<p>When enabling buffering, you can also control how the data being serialized will
be buffered. By default, an instance of CXF CachedOutputStream will be used. If you set an
"enableStreaming" property on the JAXBElementProvider then it will be a CXF CachingXMLEventWriter
that will cache the serialization events.</p>

<p>If you would like your own custom provider to write to a cached stream then you can
either set an "org.apache.cxf.output.buffering" property to 'true' on a jaxrs endpoint or
"enableBuffering" property on the provider. If this provider deals with XML and has a "getEnableStreaming"
method returning 'true' then CachingXMLEventWriter will be used, in all other cases CachedOutputStream
will be used.</p>

<p>Please note that if you don't have wrapper types for your methods and the classloader
you are using does not allow you to call defineClass(), you may need to set '-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize'</p>

<p>Marshall, unmarshall and context properties can be configured as well for both JAXB
and JSON providers.</p>

<h2><a name="JAX-RSDataBindings-JSONsupport"></a>JSON support</h2>

<p>Default JSON provider relies on Jettison 1.1 and it expects the types it deals with
to follow the same techniques as described above in the JAXB support section for them to be
handled properly. </p>

<p>Following code returns a Customer object that is marshaled to JSON format:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/customerservice/"</span>)
<span class="code-keyword">public</span> class CustomerService {
    @Produces(<span class="code-quote">"application/json"</span>)
    @GET
    @Path(<span class="code-quote">"/customers/{customerId}/"</span>)
    <span class="code-keyword">public</span> Customer getCustomer(@PathParam(<span
class="code-quote">"customerId"</span>) <span class="code-object">String</span>
id) {
        ....
    }
</pre>
</div></div>

<h3><a name="JAX-RSDataBindings-ConfiguringJSONprovider"></a>Configuring
JSON provider</h3>

<p>The default JSON provider can be configured in a number of ways. For example, here's
how to set up namespace-to-prefix mappings :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;beans <span class="code-keyword">xmlns:util</span>=<span
class="code-quote">"http://www.springframework.org/schema/util"</span>&gt;</span>
<span class="code-tag">&lt;bean id=<span class="code-quote">"jaxbProvider"</span>
class=<span class="code-quote">"org.apache.cxf.jaxrs.provider.JSONProvider"</span>&gt;</span>
<span class="code-tag">&lt;property name=<span class="code-quote">"namespaceMap"</span>
ref=<span class="code-quote">"jsonNamespaceMap"</span>/&gt;</span>
<span class="code-tag">&lt;/bean&gt;</span>
<span class="code-tag">&lt;util:map id=<span class="code-quote">"jsonNamespaceMap"</span>
map-class=<span class="code-quote">"java.util.Hashtable"</span>&gt;</span>
<span class="code-tag">&lt;entry key=<span class="code-quote">"http://www.example.org/books"</span>
value=<span class="code-quote">"b"</span>/&gt;</span>
<span class="code-tag">&lt;/util:map&gt;</span>
/<span class="code-tag">&lt;beans&gt;</span>
</pre>
</div></div>

<p>Schema validation can be enabled and custom &#64;Consume and &#64;Produce
media types can be injected, see <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml"
class="external-link" rel="nofollow">this example</a> and "Customizing media types
for message body providers" and "Schema Validation Support" sections for more information.
</p>

<h3><a name="JAX-RSDataBindings-DealingwithJSONarrayserializationissues"></a>Dealing
with JSON array serialization issues </h3>

<p>There is a well known problem in the JSON community which shows itself in the wrong
serialization of List objects containing a single value only. To work around this issue, one
needs to enable a 'serializeAsArray' feature on a JSONProvider, with the additional option
of specifying the individual fields which needs to be processed accordingly using an 'arrayKeys'
property. Please see <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml"
class="external-link" rel="nofollow">this example</a> for more information. </p>

<p>Note that 'serializeAsArray' and 'arrayKeys' can be combined to produce so called
natural convention sequences. For example, given the following two class definitions :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@XmlRootElement()
@XmlType(name = <span class="code-quote">"", propOrder = {"</span>title<span
class="code-quote">", "</span>comments" })
<span class="code-keyword">public</span> <span class="code-keyword">static</span>
class Post {
    <span class="code-keyword">private</span> <span class="code-object">String</span>
title;
    <span class="code-keyword">private</span> List&lt;Comment&gt; comments
= <span class="code-keyword">new</span> ArrayList&lt;Comment&gt;();
    <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> <span class="code-object">String</span>
getTitle() {
        <span class="code-keyword">return</span> title;
    }
    <span class="code-keyword">public</span> void setComments(List&lt;Comment&gt;
comments) {
        <span class="code-keyword">this</span>.comments = comments;
    }
    <span class="code-keyword">public</span> List&lt;Comment&gt; getComments()
{
        <span class="code-keyword">return</span> comments;
    }
}
   
<span class="code-keyword">public</span> <span class="code-keyword">static</span>
class Comment {
     <span class="code-keyword">private</span> <span class="code-object">String</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> <span class="code-object">String</span>
getTitle() {
         <span class="code-keyword">return</span> title;
     }
} 
</pre>
</div></div>

<p>an instance of Post class can be serialized like this if a JSONProvider has had its
'serializeAsArray' property set to 'true' and 'arrayKeys' list property set to contain 'comments'
value :</p>

<p>&gt; {"post":{"title":"post","comments":[{"title":"comment1"},{"title":"comment2"}]}}
</p>

<p>One other property which might help during the serialization is a boolean "ignoreMixedContent"
property which lets to bypass a Jettison issue to do with outputting '$' properties when dealing
with empty strings typically encountered in mixed content trees.</p>

<p>You may request that JSONProvider ignores an 'xsi:type' attribute which is serialized
in some cases by setting a "writeXsiType" boolean property with a 'false' value.</p>

<p>You may also request that JSONProvider ignores all the namespaces during the serialization
process by setting an "ignoreNamespaces" boolean property with a 'true' value. </p>

<h3><a name="JAX-RSDataBindings-BadgerFishconvention"></a>BadgerFish convention</h3>

<p>Starting from CXF 2.2.5 it is possible to configure JSONProvider to support a BadgerFish
convention. By default a "mapped" convention is supported, set a JSONProvider "convention"
property with the value "badgerfish" if you'd like to work with the BadgerFish convention.
</p>

<h3><a name="JAX-RSDataBindings-WrappingandUnwrappingJSONsequences"></a>Wrapping
and Unwrapping JSON sequences</h3>

<p>A "wrapperName" string property can be used to append a dropped root element name
to an incoming JSON sequence for it to be deserialized properly. A "wrapperMap" map property
can be used to nominate wrapper names for individual class names. In both cases, a 'supportUnwrapped'
boolean property also has to be set. </p>

<p>A boolean "dropRootName" property can be used to tell JSONProvider that a root element
needs to be dropped.  </p>

<h2><a name="JAX-RSDataBindings-CommonJAXBandJSONconfiguration"></a>Common
JAXB and JSON configuration</h2>
<h3><a name="JAX-RSDataBindings-AutomaticJAXBElementconversionduringserialization"></a>Automatic
JAXBElement conversion during serialization</h3>

<p>In some cases, wrapping object instances into JAXBElements may affect the way XML
is produced. For example, given Base and Derived classes, returning an instance of Derived
class, with Base one being a method response type, would produce an additional xsi:type attribute
if this instance is wrapped into JAXBElement. One can set a "jaxbElementClassNames" list property
which can contain class names like "org.foo.Base", etc.</p>


<h3><a name="JAX-RSDataBindings-HandlingJAXBbeanswithoutXmlRootElementannotations"></a>Handling
JAXB beans without XmlRootElement annotations</h3>

<p>A "jaxbElementClassNames" list property mentioned in the previous section can affect
the serialization of objects of types with XmlRootElement annotations.<br/>
In some cases no XmlRootElement annotations are available on types and adding them manually
may not be an option; likewise having explicit JAXBElements in method signatures may also
be seen as too intrusive. </p>

<p>In such cases, one might want to use a "jaxbElementClassMap" map property which contains
class name to simple or expanded QName pairs. This will also lead to the automatic JAXBElement
conversion durring the serialization. Finally, 'marshalAsJaxbElement' boolean property can
be used when all the instances need to be wrapped - provided that simple class names of these
instances can be used as element names.</p>

<p>When deserializing, one can either update an existing ObjectFactory with methods
returning JAXBElements or simply set an 'unmarshalFromJaxbElement' property on either JAXB
or JSON provider. </p>

<h3><a name="JAX-RSDataBindings-Handlingexplicitcollections"></a>Handling
explicit collections</h3>

<p>JAXB and JSON providers can handle explicit collections like List, Set or base Collection.<br/>
By default they will try to deduce the name of the collection root element from a collection
member class. For example, given a Book.class whose @XmlRootElement value is 'Book', the name
of the collection name will be 'Books'.<br/>
One can override it by setting a 'collectionWrapperName' string property, like 'Books' or
'{<a href="http://books" class="external-link" rel="nofollow">http://books</a>}Book'.
</p>

<p>There's also a 'collectionWrapperMap' property available for use in more advanced
cases, when collections of different types are used, for example, when mixed collections of
objects descended from abstract classes having no @XmlRootElement tags are returned :</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag"><span class="code-comment">&lt;!-- Configure JAXB Provider
--&gt;</span></span>
&lt;bean id=<span class="code-quote">"jaxbProvider"</span>
class=<span class="code-quote">"org.apache.cxf.jaxrs.provider.JAXBElementProvider"</span>&gt;
  <span class="code-tag">&lt;property name=<span class="code-quote">"collectionWrapperMap"</span>&gt;</span>
  <span class="code-tag">&lt;map&gt;</span>
    <span class="code-tag">&lt;entry&gt;</span>
      <span class="code-tag">&lt;key&gt;</span><span class="code-tag">&lt;value&gt;</span>com.foo.bar.MyObject<span
class="code-tag">&lt;/value&gt;</span><span class="code-tag">&lt;/key&gt;</span>
      <span class="code-tag">&lt;value&gt;</span>MyObjects<span class="code-tag">&lt;/value&gt;</span>
    <span class="code-tag">&lt;/entry&gt;</span>
   <span class="code-tag">&lt;/map&gt;</span>
   <span class="code-tag">&lt;/property&gt;</span>
<span class="code-tag">&lt;/bean&gt;</span> 
</pre>
</div></div>

<p>JSONProvider can only serialize explicit collections at the moment. If needed, it
can be told to drop a collection element name using a boolean 'dropCollectionWrapperElementName'.
For example, a 'dropCollectionWrapperElementName' and 'serializeAsArray' properties can be
used to make the Dojo JSON RestStore consume the resulting JSON sequence (in CXF 2.2.5).</p>

<h3><a name="JAX-RSDataBindings-CustomizingJAXBXMLandJSONinputandoutput"></a>Customizing
JAXB XML and JSON input and output</h3>

<p>Sometimes you may want to adapt an incoming XML request or outgoing XML response.
For example, your application has changed but a lot of legacy clients have not been updated
yet.<br/>
When dealing with XML, the easiest and fastest option is to register a custom STAX XMLStreamWriter
or XMLStreamReader and modify XML as needed. You can register a custom STAX <br/>
handler from RequestHandler or ResponseHandler filters or input/output CXF interceptors. For
example, see <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/XmlStreamWriterProvider.java"
class="external-link" rel="nofollow">XMLStreamWriterProvider</a> and <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomXmlStreamWriter.java"
class="external-link" rel="nofollow">CustomXmlStreamWriter</a>.</p>

<p>Another option is to register a custom JAXB or JSON provider extending CXF JAXBElementProvider
or JSONProvider and overriding a method like createStreamWriter(). <br/>
Typically one would delegate to a super class first and then wrap the returned writer in a
custom writer, see <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomXmlStreamWriter.java"
class="external-link" rel="nofollow">CustomXmlStreamWriter</a> for an example.</p>

<p>One can also use XSLTJaxbProvider to produce or modify the incoming XML. In fact,
XSLTJaxbProvider can be used to adapt formats like JSON for legacy consumers.</p>

<p>Please also see this <a href="http://soa.dzone.com/articles/pragmatic-web-services-apache"
class="external-link" rel="nofollow">overview</a> of various related features available
in CXF. </p>

<p>In CXF 2.2.5, a new feature has been introduced whose goal is to generalize and simplify
in a number of cases the way both JAXB and JSON can be customized.</p>

<p>The following configuration properties have been added to the base JAXB/JSON AbstractJAXBProvider
:</p>

<ul class="alternate" type="square">
	<li>"outTransformElements" map property : can be used to change the output element
names and change or drop namespaces; keys are the elements to be changed, values are the new
element names. Examples:</li>
</ul>


<p>&gt;  book:thebook - change "book" to "thebook"<br/>
&gt;  {<a href="http://books" class="external-link" rel="nofollow">http://books</a>}book:book
- drop the namespace from "book"<br/>
&gt;  book:{<a href="http://books" class="external-link" rel="nofollow">http://books</a>}thebook
- qualify "book" with "http://books"<br/>
&gt;  {<a href="http://book" class="external-link" rel="nofollow">http://book</a>}&#42;:{<a
href="http://books" class="external-link" rel="nofollow">http://books</a>}&#42;
- change namespace to "http://books" for all the elements with the "http://book" namespace</p>

<ul class="alternate" type="square">
	<li>"inTransformElements" map property : can be used to change the input element names
and change or drop namespaces; see "outElementsMap"</li>
</ul>


<ul class="alternate" type="square">
	<li>"outAppendElements" map property : can be used to append new simple or qualified
elements to the output; keys are the new elements, values are the elements the new ones will
be appended before. Examples:</li>
</ul>


<p>&gt;  book:thebook - append "book" before "thebook"<br/>
&gt;  {<a href="http://books" class="external-link" rel="nofollow">http://books</a>}book:book
- append the namespace to the "book"<br/>
&gt;  book:{<a href="http://books" class="external-link" rel="nofollow">http://books</a>}book
- drop the namespace from the "book"<br/>
&gt;  {<a href="http://book" class="external-link" rel="nofollow">http://book</a>}&#42;:{<a
href="http://books" class="external-link" rel="nofollow">http://books</a>}&#42;
- change namespace to "http://books" for all the elements with the "http://book" namespace</p>


<ul class="alternate" type="square">
	<li>"inAppendElements" map property : can be used to append new simple or qualified
elements to the input; see "outAppendMap"</li>
</ul>


<ul class="alternate" type="square">
	<li>"outDropElements" list property : can be used to drop elements during the serialization;
note that children elements if any of a given dropped element are not affected. Examples:</li>
</ul>


<p>&gt;  index, {<a href="http://numbers" class="external-link" rel="nofollow">http://numbers</a>}number
- drop "index" and {<a href="http://numbers" class="external-link" rel="nofollow">http://numbers</a>}number
elements</p>

<ul class="alternate" type="square">
	<li>"inDropElements" list property : can be used to drop elements during the deserialization;
note that children elements if any of a given dropped element are not affected.</li>
</ul>


<ul class="alternate" type="square">
	<li>"attributesAsElements" boolean property : can be used to have attributes be serialized
as elements.</li>
</ul>


<p>The combination of "attributesAsElements" and "outDropElements" properties can be
used to have certain attributes ignored in the output.</p>

<p>This feature might be used in a number of cases. For example, one may have rootless
JSON array collections such as "<tt>a:b},{c:d</tt>" deserialized into a bean by
using a "wrapperName" JSONProvider property with a value like "list" which identifies a bean
field and an "inAppendMap" property with a name of the bean (ex, "book") being appended before
the "list", thus effectively turning the original JSON sequence into "{book:{list:<tt>a:b},{c:d</tt>}}".</p>

<h2><a name="JAX-RSDataBindings-Atom"></a>Atom</h2>

<p>CXF JAXRS offers users 3 options for dealing with Atom</p>

<p>1. Register Apache Abdera based Feed and/or Entry providers (org.apache.cxf.jaxrs.provider.AtomFeedProvider
and org.apache.cxf.jaxrs.provider.AtomEntryProvider) with a jaxrs endpoint and have resource
methods explicitly dealing with Abdera Feed or Entry classes. This is the most advanced option
in that it lets users build Feeds or Entries in the way which suits most. Note that Abdera
has not been actively mantained recently but practically speaking it is very good for working
with most of the cases one may have to deal with when developing Atom-based applications.
</p>

<p>Both AtomFeedProvider and AtomEntryProvider support a 'formattedOutput' (pretty-printing)
property.</p>

<p>2. Register an <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AtomPojoProvider.java"
class="external-link" rel="nofollow">AtomPojoProvider</a> injected with either <a
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/atom/AtomElementWriter.java"
class="external-link" rel="nofollow">AtomElementWriter</a> or <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/atom/AtomElementReader.java"
class="external-link" rel="nofollow">AtomElementReader</a> implementations parameterized
by either Abdera Feed or Entry and type of object which will have to be converted to/read
from Feed/Entry. For example, BookAtomElementWriter\&lt;Feed, Book&gt; will be responsible
for converting Book instances into Feeds while ChapterAtomElementWriter\&lt;Entry, Chapter&gt;
will be responsible for converting Chapter instances into Entries.</p>

<p>AtomElementWriter and AtomElementReader are injected using 'atomWriters' and 'atomReaders'
map properties, where the keys are class names of the objects to be converted to/read from
Feed or Entries, ex "org.apache.cxf.systest.jaxrs.Book". </p>

<p>AtomPojoProvider offers users a way to have no Abdera Feed/Entry classes referenced
from the 'main' application code, example :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"books"</span>)
<span class="code-keyword">public</span> class BooksRootResource {

 <span class="code-keyword">private</span> Books books;

 @GET
 @Produces({<span class="code-quote">"application/xml"</span>, <span class="code-quote">"application/json"</span>,
<span class="code-quote">"application/atom+xml;type=feed"</span>})
 <span class="code-keyword">public</span> Books getCollectionOfBooks() {
     <span class="code-keyword">return</span> books;
 } 

 @GET
 @Produces({<span class="code-quote">"application/xml"</span>, <span class="code-quote">"application/json"</span>,
<span class="code-quote">"application/atom+xml;type=entry"</span>})
 @Path(<span class="code-quote">"{id}"</span>)
 <span class="code-keyword">public</span> Book getBook(@PathParam(<span class="code-quote">"id"</span>)
<span class="code-object">Long</span> id) {
     <span class="code-keyword">return</span> books.get(id);
 }

}
</pre>
</div></div> 

<p>Note that when an object such as Books is about to be converted to/read from Feed
(which in our case is essentially a collection of entries each of them representing an individual
Book) the AtomPojoProvider needs to know about the collection getters and/or setters so that
it can create individual Entries. The "collectionGetters" and "collectionSetters" map properties
with keys being the names of collection classes and values being the method names need to
be used for providing this information, example a pair "org.apache.cxf.systest.jaxrs.Books:getBooks"
tells AtomPojoProvider that when creating a Books Feed, the objects representing individual
entries can be retrieved from Book with the help of "getBooks". If these properties are not
set then AtomPojoProvider will try to get a method adding the simple class name to either
'get' or 'set', for example, an "org.apache.cxf.systest.jaxrs.Books:getBooks" pair is redundant
if the Books class has a getBooks method.</p>

<p>3. This option is nearly identical to the option 2, except that users configure AtomPojoProvider
with concrete implementations of either <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/atom/AbstractFeedBuilder.java"
class="external-link" rel="nofollow">AbstractFeedBuilder</a> or <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/atom/AbstractEntryBuilder.java"
class="external-link" rel="nofollow">AbstractEntryBuilder</a>.</p>

<p>The difference is that in this case users have no explicit dependencies in their
code on Atom-aware libraries such as Abdera - it may make it easier to experiment with various
Atom libraries.</p>

<h2><a name="JAX-RSDataBindings-AegisDataBinding"></a>Aegis Data Binding</h2>

<p>Use org.apache.cxf.provider.AegisElementProvider to start doing Aegis with JAX-RS<br/>
org.apache.cxf.provider.AegisJSONProvider can be used to output JSON with the help of Aegis.<br/>
Similarly to the default JSONProvider this Aegis-based JSON provider can have "namespaceMap",
"serializeAsArray", "arrayKeys", "dropRootElement" and "writeXsiType" properties set.</p>

<h2><a name="JAX-RSDataBindings-XMLBeans"></a>XMLBeans</h2>

<p>Use org.apache.cxf.provider.XmlBeansElementProvider to start doing XmlBeans with
JAX-RS</p>

<h2><a name="JAX-RSDataBindings-CXFDataBindings"></a>CXF DataBindings</h2>

<p>Starting from CXF 2.2.3 it is now possible to register a CXF DataBinding bean using
a jaxrs:databinding element and it will be wrappped as a JAXRS MessageBodyReader/Writer <a
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/DataBindingProvider.java"
class="external-link" rel="nofollow">DataBindingProvider</a> capable of dealing with
XML-based content. It can be of special interest to users combining JAX-RS and JAXWS. Thus
CXF JAXB, Aegis, SDO and XMLBeans databindings can be easily plugged in.<br/>
JSON support is also provided for all these databindings by <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/DataBindingJSONProvider.java"
class="external-link" rel="nofollow">DataBindingJSONProvider</a>.<br/>
Please see <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_databinding/WEB-INF/beans.xml"
class="external-link" rel="nofollow">this configuration file</a> for some examples.</p>

<p>Similarly to the default JSONProvider the DataBindingJSONProvider JSON provider can
have "namespaceMap", "serializeAsArray", "arrayKeys", "dropRootElement" and "writeXsiType"
properties set. Additionally it may also have an "ignoreMixedContent" property set.</p>

<p>Note that at the moment this feature is only available on the trunk. JAXB and Aegis
DataBindings (XML only) is supported in CXF 2.2.3.</p>

<h2><a name="JAX-RSDataBindings-Schemavalidation"></a>Schema validation</h2>

<p>There're two ways you can enable a schema validation.</p>

<p>1. Using jaxrs:schemaLocations element :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;beans <span class="code-keyword">xmlns:util</span>=<span
class="code-quote">"http://www.springframework.org/schema/util"</span>&gt;</span>
<span class="code-tag">&lt;jaxrs:server address=<span class="code-quote">"/"</span>&gt;</span>
  <span class="code-tag">&lt;jaxrs:schemaLocations&gt;</span>
     <span class="code-tag">&lt;jaxrs:schemaLocation&gt;</span>classpath:/schemas/a.xsd<span
class="code-tag">&lt;/jaxrs:schemaLocation&gt;</span>
     <span class="code-tag">&lt;jaxrs:schemaLocation&gt;</span>classpath:/schemas/b.xsd<span
class="code-tag">&lt;/jaxrs:schemaLocation&gt;</span>
  <span class="code-tag">&lt;/jaxrs:schemaLocations&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>
/<span class="code-tag">&lt;beans&gt;</span>
</pre>
</div></div>

<p>Using this option is handy when you have multiple bindings involved which support
the schema validation. In this case<br/>
individual MessageBodyReader implementations which have a method setSchemas(List&lt;Sring&gt;
schemaLocations) called. Default JAXBElementProvider and JSONProvider which rely on JAXB can
be enabled to do the validation this way. In the above example two schema documents are provided,
with b.xsd schema presumably importing a.xsd  </p>

<p>2. Configuring providers individually</p>

<p>Please see <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml"
class="external-link" rel="nofollow">this example</a> of how both JAXB and JSON providers
are using a shared schema validation configuration.</p>

<h2><a name="JAX-RSDataBindings-FastInfoset"></a>Fast Infoset</h2>

<p>You can enable the <a href="https://fi.dev.java.net/standardization.html" class="external-link"
rel="nofollow">FastInfoset</a> by explicitly registering CXF FastInfoset interceptors
with a JAXRS endpoint and configuring JAXBElementProvider to support an "application/fastinfoset"
media type :<br/>
for example :</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">

<span class="code-tag">&lt;jaxrs:server id=<span class="code-quote">"restservice3"</span>
address=<span class="code-quote">"/rest3"</span>&gt;</span>

 <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
  <span class="code-tag">&lt;ref bean=<span class="code-quote">"bookstore"</span>/&gt;</span>
 <span class="code-tag">&lt;/jaxrs:serviceBeans&gt;</span>

 <span class="code-tag">&lt;jaxrs:providers&gt;</span>
  <span class="code-tag">&lt;ref bean=<span class="code-quote">"jaxbProvider"</span>/&gt;</span>
 <span class="code-tag">&lt;/jaxrs:providers&gt;</span>

 <span class="code-tag">&lt;jaxrs:outInterceptors&gt;</span>
  <span class="code-tag">&lt;ref bean=<span class="code-quote">"fastInfosetOutInterceptor"</span>/&gt;</span>
 <span class="code-tag">&lt;/jaxrs:outInterceptors&gt;</span>

 <span class="code-tag">&lt;jaxrs:inInterceptors&gt;</span>
  <span class="code-tag">&lt;ref bean=<span class="code-quote">"fastInfosetInInterceptor"</span>/&gt;</span>
 <span class="code-tag">&lt;/jaxrs:inInterceptors&gt;</span>

 <span class="code-tag">&lt;jaxrs:properties&gt;</span>
  <span class="code-tag">&lt;entry key=<span class="code-quote">"org.apache.cxf.endpoint.private"</span>
value=<span class="code-quote">"true"</span>/&gt;</span>
 <span class="code-tag">&lt;/jaxrs:properties&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>

<span class="code-tag">&lt;util:list id=<span class="code-quote">"fastinfosetType"</span>&gt;</span>
  <span class="code-tag">&lt;value&gt;</span>application/fastinfoset<span
class="code-tag">&lt;/value&gt;</span>
<span class="code-tag">&lt;/util:list&gt;</span>

<span class="code-tag">&lt;bean id=<span class="code-quote">"jaxbProvider"</span>
class=<span class="code-quote">"org.apache.cxf.jaxrs.provider.JAXBElementProvider"</span>&gt;</span>
  <span class="code-tag">&lt;property name=<span class="code-quote">"produceMediaTypes"</span>
ref=<span class="code-quote">"fastinfosetType"</span>/&gt;</span>
  <span class="code-tag">&lt;property name=<span class="code-quote">"consumeMediaTypes"</span>
ref=<span class="code-quote">"fastinfosetType"</span>/&gt;</span>
<span class="code-tag">&lt;/bean&gt;</span>
<span class="code-tag">&lt;bean id=<span class="code-quote">"fastInfosetOutInterceptor"</span>
class=<span class="code-quote">"org.apache.cxf.interceptor.FIStaxOutInterceptor"</span>/&gt;</span>
<span class="code-tag">&lt;bean id=<span class="code-quote">"fastInfosetInInterceptor"</span>
class=<span class="code-quote">"org.apache.cxf.interceptor.FIStaxInInterceptor"</span>/&gt;</span>
</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/JAX-RS+Data+Bindings">View
Online</a>
              |
       <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+Data+Bindings?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
           </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message