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 Advanced Features
Date Wed, 22 Dec 2010 14:08: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+Advanced+Features">JAX-RS
Advanced Features</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~sergey_beryozkin">Sergey
Beryozkin</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" >By referencing a bean such as &#39;org.apache.cxf.systest.jaxrs.JMSBookStore&#39;
from multiple jaxrs endpoints you can ensure that both HTTP and JMS requests are handled by
the same service bean. In such cases you may want to use a CXF JAXRS specific [ProtocolHeaders|http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ProtocolHeaders.java]
context which will let you get either HTTP or JMS headers.  <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h1.
FIQL search queries <br> <br>CXF JAXRS (since 2.3.0) lets users do the advanced
search queries based on the [Feed Item Query Language|http://tools.ietf.org/html/draft-nottingham-atompub-fiql-00](FIQL).
FIQL lets users express complex search expressions using an intuitive and URI friendly language.
<br> <br>For example, a query such as <br> <br>{code:java} <br>?_search=name==CXF;version=ge=2.2
<br>{code} <br> <br>lets users to search for all the Apache projects with
the name &#39;CXF&#39; and the version greater or equals to &#39;2.2&#39;.
The initial &#39;=&#39; separates the name of the query &#39;_search&#39;
from the FIQL expression, while &#39;==&#39; and &#39;=ge=&#39; convey &#39;equals
to&#39; and &#39;greater or equals to&#39; respectively. <br> <br>More
complex composite expressions can also be expressed easily enough. <br> <br>Note
that either &#39;_search&#39; or &#39;_s&#39; query has to be used to pass
the FIQL expression. <br> <br>To avail of this feature, a [SearchContext|http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContext.java]
can be injected into an application code and used to retrieve a [SearchCondition|http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchCondition.java]
representing the current FIQL query. This SearchCondition can be used in a number of ways
for finding the matching data. <br> <br>For example : <br> <br>{code:java}
<br>@Path(&quot;books&quot;) <br>public class Books { <br> <br>private
Map&lt;Long, Book&gt; books; <br>@Context <br>private SearchContext context;
<br> <br> @GET <br> public List&lt;Book&gt; getBook() { <br>
<br>   SearchCondition&lt;Book&gt; sc = searchContext.getCondition(Book.class);
<br>   // SearchCondition#isMet method can also be used to build a list of matching
beans <br>   List&lt;Book&gt; found = sc.findAll(books.values()); <br>
  return found; <br> } <br>} <br>{code} <br> <br>SearchCondition
can also be used to get to all the search requirements (originally expressed in FIQL) and
do some manual <br>comparison against the local data. For example, SearchCondition provides
a utility toSQL(String tableName, String... columnNames) method which internally introspects
all the search expressions constituting a current query and converts them into an SQL expression
: <br> <br>{code:java} <br>// find all conditions with names starting from
&#39;ami&#39;  <br>// and levels greater than 10 : <br>// ?_s=&quot;name==ami*;level=gt=10&quot;
<br>SearchCondition&lt;Book&gt; sc = searchContext.getCondition(Book.class);
<br>assertEquals(&quot;SELECT * FROM table  <br>              WHERE  <br>
             name LIKE &#39;ami%&#39;  <br>              AND  <br>   
          level &gt; &#39;10&#39;&quot;, <br>              sq.toSQL(&quot;table&quot;));
<br>{code} <br> <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h1. Oneway invocations <br>
<br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
        </table>
</div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <span style="font-size:2em;font-weight:bold">JAX-RS : Advanced Features</span>

<div>
<ul>
    <li><a href='#JAX-RSAdvancedFeatures-JMSSupport'>JMS Support</a></li>
    <li><a href='#JAX-RSAdvancedFeatures-FIQLsearchqueries'>FIQL search queries</a></li>
    <li><a href='#JAX-RSAdvancedFeatures-Onewayinvocations'>Oneway invocations</a></li>
    <li><a href='#JAX-RSAdvancedFeatures-SupportforContinuations'>Support for
Continuations</a></li>
    <li><a href='#JAX-RSAdvancedFeatures-RESTfulserviceswithoutannotations'>RESTful
services without annotations</a></li>
<ul>
    <li><a href='#JAX-RSAdvancedFeatures-Configuration'>Configuration</a></li>
</ul>
</ul></div>

<h1><a name="JAX-RSAdvancedFeatures-JMSSupport"></a>JMS Support</h1>

<p>CXF has been designed such that multiple transports can be supported for a given
endpoint. If you would like your JAXRS endpoint be capable of serving not only HTTP but also
JMS requests then you need to specify a JMS transportId, 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 serviceName=<span class="code-quote">"s:BookService"</span>
transportId=<span class="code-quote">"http://cxf.apache.org/transports/jms"</span>
address=<span class="code-quote">"/"</span>&gt;</span>
 <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
   <span class="code-tag">&lt;bean class=<span class="code-quote">"org.apache.cxf.systest.jaxrs.JMSBookStore"</span>/&gt;</span>
 <span class="code-tag">&lt;/jaxrs:serviceBeans&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>
</pre>
</div></div> 

<p>Additionally, JMS queue or topic <a href="http://cxf.apache.org/docs/using-the-jmsconfigfeature.html"
class="external-link" rel="nofollow">configuration</a> needs to be done, for example,
please see this <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/jms_server_config.xml"
class="external-link" rel="nofollow">beans.xml</a>. Please note how a serviceName
attribute is used to specify a service QName for a jaxrs endpoint (default is {<a href="http://reverse.package.name"
class="external-link" rel="nofollow">http://reverse.package.name</a>}ServiceClassName),
this service name is <br/>
used to configure a jms destination.</p>

<p>Here is the actual <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSJmsTest.java"
class="external-link" rel="nofollow">test</a>. </p>

<p>Here are JMS properties which can help with matching a required method on the JAXRS
endpoint :</p>
<ul class="alternate" type="square">
	<li>"Content-Type" : default is "text/xml"</li>
	<li>"Accept" : default is "<b>/</b>"</li>
	<li>"OnewayMessage" : default is "false"</li>
	<li>"org.apache.cxf.message.Message.REQUEST_URI" : default is "/"</li>
	<li>"org.apache.cxf.message.Message.HTTP_REQUEST_METHOD" : default is "POST"</li>
</ul>


<p>If JMS messages are sent to topic destinations then one has to either set a "OnewayMessage"
property or ensure that target JAXRS methods are annotated with org.apache.cxf.jaxrs.ext.Oneway.
</p>

<p>As far as REQUEST_URI is concerned, it is initially matched against a jaxrs:server/@address.
So if REQUEST_URI is not set or set to "/" then jaxrs:server/@address has to be set to "/".
If REQUEST_URI is set to "/bar/foo" and<br/>
jaxrs:server/@address is set to "/bar" then it will be '/foo' which will be used to find a
root resource class and its method.</p>

<p>By referencing a bean such as 'org.apache.cxf.systest.jaxrs.JMSBookStore' from multiple
jaxrs endpoints you can ensure that both HTTP and JMS requests are handled by the same service
bean. In such cases you may want to use a CXF JAXRS specific <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ProtocolHeaders.java"
class="external-link" rel="nofollow">ProtocolHeaders</a> context which will let you
get either HTTP or JMS headers. </p>

<h1><a name="JAX-RSAdvancedFeatures-FIQLsearchqueries"></a>FIQL search queries</h1>

<p>CXF JAXRS (since 2.3.0) lets users do the advanced search queries based on the <a
href="http://tools.ietf.org/html/draft-nottingham-atompub-fiql-00" class="external-link" rel="nofollow">Feed
Item Query Language</a>(FIQL). FIQL lets users express complex search expressions using
an intuitive and URI friendly language.</p>

<p>For example, a query such as</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
?_search=name==CXF;version=ge=2.2
</pre>
</div></div>

<p>lets users to search for all the Apache projects with the name 'CXF' and the version
greater or equals to '2.2'. The initial '=' separates the name of the query '_search' from
the FIQL expression, while '==' and '=ge=' convey 'equals to' and 'greater or equals to' respectively.</p>

<p>More complex composite expressions can also be expressed easily enough.</p>

<p>Note that either '_search' or '_s' query has to be used to pass the FIQL expression.</p>

<p>To avail of this feature, a <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContext.java"
class="external-link" rel="nofollow">SearchContext</a> can be injected into an application
code and used to retrieve a <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchCondition.java"
class="external-link" rel="nofollow">SearchCondition</a> representing the current
FIQL query. This SearchCondition can be used in a number of ways for finding the matching
data.</p>

<p>For 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 Books {

<span class="code-keyword">private</span> Map&lt;<span class="code-object">Long</span>,
Book&gt; books;
@Context
<span class="code-keyword">private</span> SearchContext context;

 @GET
 <span class="code-keyword">public</span> List&lt;Book&gt; getBook() {

   SearchCondition&lt;Book&gt; sc = searchContext.getCondition(Book.class);
   <span class="code-comment">// SearchCondition#isMet method can also be used to build
a list of matching beans
</span>   List&lt;Book&gt; found = sc.findAll(books.values());
   <span class="code-keyword">return</span> found;
 }
}
</pre>
</div></div>

<p>SearchCondition can also be used to get to all the search requirements (originally
expressed in FIQL) and do some manual<br/>
comparison against the local data. For example, SearchCondition provides a utility toSQL(String
tableName, String... columnNames) method which internally introspects all the search expressions
constituting a current query and converts them into an SQL expression :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-comment">// find all conditions with names starting from 'ami' 
</span><span class="code-comment">// and levels greater than 10 :
</span><span class="code-comment">// ?_s=<span class="code-quote">"name==ami*;level=gt=10"</span>
</span>SearchCondition&lt;Book&gt; sc = searchContext.getCondition(Book.class);
assertEquals("SELECT * FROM table 
              WHERE 
              name LIKE 'ami%' 
              AND 
              level &gt; '10'",
              sq.toSQL(<span class="code-quote">"table"</span>));
</pre>
</div></div>


<h1><a name="JAX-RSAdvancedFeatures-Onewayinvocations"></a>Oneway invocations</h1>

<p>Resource methods with an org.apache.cxf.jaxrs.ext.Oneway annotation will be invoked
oneway with the original request returning 202 HTTP status. HTTP or JMS clients can also add
a "OnewayRequest" header if adding Oneway annotations is not an option.</p>

<h1><a name="JAX-RSAdvancedFeatures-SupportforContinuations"></a>Support
for Continuations </h1>

<p>Please see <a href="http://sberyozkin.blogspot.com/2008/12/continuations-in-cxf.html"
class="external-link" rel="nofollow">this blog entry</a> describing how JAXRS (and
indeed) JAXWS services can rely on the CXF Continuations API. </p>

<p>Please see the <a href="/confluence/pages/createpage.action?spaceKey=CXF20DOC&amp;title=CXF+Continuations&amp;linkCreation=true&amp;fromPageId=24190907"
class="createlink">CXF Continuations</a> page for more information.</p>


<h1><a name="JAX-RSAdvancedFeatures-RESTfulserviceswithoutannotations"></a>RESTful
services without annotations </h1>

<p>One of the latest CXF JAX-RS extensions allows users to provide external models with
the information which the runtime typically gets from JAX-RS annotations like @Path, @PathParam,
@Consumes, @Produces, etc.<br/>
There might be a number of cases when it can be advantageous to describe how a given resource
can be exposed as a RESTful service without actually modifying this resource. For example,
when new dynamic interface implementations are registered, when no source code can be modified,
when the cost of future updates (for ex, modifying the value of @Path annotations) is considered
to be expensive, etc.</p>

<p>User model schema type is described in the <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs.xsd"
class="external-link" rel="nofollow">jaxrs.xsd</a>. </p>

<p>The top-level 'model' element can have 'resource' children elements. A 'resource'
element describes a resource class which can be either a root resource class or a sub-resource
one and it can have attributes describing 'path', 'produces' and 'consumes' values and it
has a 'name' attribute which identifies a fully-qualified resource class. <br/>
A 'resource' element can have a number of 'operation' elements pointing to resource methods
(with its 'name' attribute) and can have 'path', 'produces', 'consumes' and 'verb' (HTTP method)
values. An 'operation' element which has no 'verb' attribute is treated as a sub-resource
locator - a corresponding resource class has to be available in the model with its 'name'
attribute matching the return type's name of this operation.<br/>
Every operation can have a number of 'param' elements. A 'param' element should have its 'name'
attribute matching a corresponding parameter name in the class resource method. Its 'type'
can have the following values : 'PATH', 'QUERY', 'CONTEXT', 'HEADER', 'MATRIX', 'COOKIE',
'FORM' or 'REQUEST_BODY'. Parameters corresponding to response types do not have to be described.
It can also have 'defaultValue' and 'encoded' values being set.</p>

<p>Starting from CXF 2.3.2-SNAPSHOT a "oneway" attribute can also be applied to individual
operations.</p>

<p>Here is an example :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;model xmlns=<span class="code-quote">"http://cxf.apache.org/jaxrs"</span>&gt;</span>
  &lt;resource name=<span class="code-quote">"org.apache.cxf.systest.jaxrs.BookStoreNoAnnotations"</span>
path=<span class="code-quote">"bookstore"</span>
    produces=<span class="code-quote">"application/json"</span> consumes=<span
class="code-quote">"application/json"</span>&gt;
    <span class="code-tag">&lt;operation name=<span class="code-quote">"getBook"</span>
verb=<span class="code-quote">"GET"</span> path=<span class="code-quote">"/books/{id}"</span>
produces=<span class="code-quote">"application/xml"</span>&gt;</span>
       <span class="code-tag">&lt;param name=<span class="code-quote">"id"</span>
type=<span class="code-quote">"PATH"</span>/&gt;</span>
    <span class="code-tag">&lt;/operation&gt;</span>
    <span class="code-tag">&lt;operation name=<span class="code-quote">"getBookChapter"</span>
path=<span class="code-quote">"/books/{id}/chapter"</span>&gt;</span>
       <span class="code-tag">&lt;param name=<span class="code-quote">"id"</span>
type=<span class="code-quote">"PATH"</span>/&gt;</span>
    <span class="code-tag">&lt;/operation&gt;</span>
    <span class="code-tag">&lt;operation name=<span class="code-quote">"updateBook"</span>
verb=<span class="code-quote">"PUT"</span>&gt;</span>
       <span class="code-tag">&lt;param name=<span class="code-quote">"book"</span>
type=<span class="code-quote">"REQUEST_BODY"</span>/&gt;</span>
    <span class="code-tag">&lt;/operation&gt;</span>
  <span class="code-tag">&lt;/resource&gt;</span>
  <span class="code-tag">&lt;resource name=<span class="code-quote">"org.apache.cxf.systest.jaxrs.ChapterNoAnnotations"</span>&gt;</span>
    <span class="code-tag">&lt;operation name=<span class="code-quote">"getItself"</span>
verb=<span class="code-quote">"GET"</span>/&gt;</span>
    <span class="code-tag">&lt;operation name=<span class="code-quote">"updateChapter"</span>
verb=<span class="code-quote">"PUT"</span> consumes=<span class="code-quote">"application/xml"</span>&gt;</span>
        <span class="code-tag">&lt;param name=<span class="code-quote">"content"</span>
type=<span class="code-quote">"REQUEST_BODY"</span>/&gt;</span>
    <span class="code-tag">&lt;/operation&gt;</span>
  <span class="code-tag">&lt;/resource&gt;</span>
<span class="code-tag">&lt;/model&gt;</span>
</pre>
</div></div>

<p>This model describes two resources, BookStoreNoAnnotations and ChapterNoAnnotations.
The BookStoreNoAnnotations resource has three resource operations, 'getBook', 'getBookChapter'
and 'updateBook'. Note that the 'getBookChapter' operation element (described in the model)
has no 'verb' attribute so runtime will identify it as a subresource locator.<br/>
The runtime will introspect the <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreNoAnnotations.java"
class="external-link" rel="nofollow">org.apache.cxf.systest.jaxrs.BookStoreNoAnnotations</a>
class and check the return types for both 'getBook' and 'getBookChapter' methods.  BookStoreNoAnnotations.getBookChapter()
method's return type is <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/ChapterNoAnnotations.java"
class="external-link" rel="nofollow">org.apache.cxf.systest.jaxrs.ChapterNoAnnotations</a>
so the model will be checked if it contains the resource element with the 'name' attribute
equal to 'org.apache.cxf.systest.jaxrs.ChapterNoAnnotations'. After this resource has been
found, the  ChapterNoAnnotations class is recognized as a sub-resource and then its 'getItself'
method is checked.  </p>

<p>Additionally the BookStoreNoAnnotations resource declares that all its resource methods
produce 'application/json' mediaTypes, while its 'getBook' method overrides its with its own
'produces' value. BookStoreNoAnnotations resource also has a 'consumes' attribute which requires
all of the resource methods (such as 'updateBook') to consume "application/json" formats.
The ChapterNoAnnotations 'updateChapter' resource operation requires 'application/xml' formats.</p>

<p>You can use a comma-seperated list of media type values if needed, for example, produces("application/xml;charset=utf-8,application/json")
or consumes("application/xml;charset=utf-8,application/json").</p>

<p>Please also see this <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/resources2.xml"
class="external-link" rel="nofollow">model file</a> for an example. Providing this
file will let all implementations of the interface described in this model instance be exposed
as RESTful services supported by the JAX-RS runtime. </p>

<h2><a name="JAX-RSAdvancedFeatures-Configuration"></a>Configuration </h2>

<p>A user model can be referenced in a number of ways. It can be embedded in a jaxrs:server
endpoint definition or linked to through a jaxrs:server modelRef attribute as a classpath
resource. </p>

<p>Please see this <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">bean</a> Spring configuration file, look at
jaxrs server beans with 'bookservice6' and 'bookservice7' names.</p>

<p>Note that when registering a model from Spring you do not need to declare a jaxrs
server serviceBeans section - the runtime will instantiate the beans itself. If you do need
to inject certain properties into your service bean from Spring then you do need to declare
a service bean too. In this case this bean will be instantiated twice - once by the runtime
during the model introspection and once by Spring, however in the end it will be the bean
created by Spring that will be used, the one created by the runtime will be removed.<br/>
You can avoid this double instantiation by having your model describing the interfaces which
the actual root resource beans will implement. In this case only Spring will create a bean
and the runtime will apply the model description to this injected bean. Note that if Spring
proxifies your bean (for example by applying transaction aspects to it) then the model does
have to describe an interface for a match between the model and the injected bean proxy to
succeed.</p>

<p>Please have a look at <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_proxy/WEB-INF/beans.xml"
class="external-link" rel="nofollow">this Spring bean</a>. The jaxrs endpoint with
id 'bookservice2' will have BookStoreWithNoAnnotations created twice but it will be the Spring
created BookStoreWithNoAnnotations bean that will serve as a resource class instance. The
jaxrs endpoint with id 'bookservice3' will have BookStoreWithNoAnnotationsImpl class instantiated
only by Spring, with the model describing BookStoreWithNoAnnotationsInterface only that this
class implements.</p>


<p>You can also register a model programmatically, for example :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
JAXRSServerFactoryBean sf = <span class="code-keyword">new</span> JAXRSServerFactoryBean();
            sf.setAddress(<span class="code-quote">"http:<span class="code-comment">//localhost:9080/"</span>);
</span><span class="code-object">String</span> modelRef = <span class="code-quote">"classpath:/org/apache/cxf/systest/jaxrs/resources/resources2.xml"</span>;
sf.setModelRef(modelRef);

<span class="code-comment">// or <span class="code-keyword">if</span> you
have <span class="code-keyword">interface</span> classes described in the model
already loaded, ex : OSGI
</span><span class="code-comment">// sf.setModelRefWithServiceClass(modelRef,
BookStoreNoAnnotationsInterface.class);
</span>
<span class="code-comment">// register an actual bean only <span class="code-keyword">if</span>
the model describes interfaces
</span>sf.setServiceBeans(<span class="code-keyword">new</span> BookStoreNoAnnotationsImpl());
</pre>
</div></div>

<p>Please also see <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerUserResourceTest.java"
class="external-link" rel="nofollow">this system test</a> for the example of how
model beans like UserResource can be created and registered programmatically.</p>

<p>Similarly, you can register a user model on the client side, either from jaxrs:client
or programmatically, example :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
JAXRSClientFactoryBean cf = <span class="code-keyword">new</span> JAXRSClientFactoryBean();
cf.setAddress(<span class="code-quote">"http:<span class="code-comment">//localhost:9080/"</span>);
</span><span class="code-object">String</span> modelRef = <span class="code-quote">"classpath:/org/apache/cxf/systest/jaxrs/resources/resources2.xml"</span>;
sf.setModelRef(modelRef);
BookStoreNoAnnotations proxy = cf.create(BookStoreNoAnnotations.class);
</pre>
</div></div>

<p>At the moment it is only possible to register a user model with CXFNonSpringJAXRSServlet
using the latest 2.2.3-SNAPSHOT like the way it is done in this <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_non_spring/WEB-INF/web.xml"
class="external-link" rel="nofollow">web.xml</a>. See CXFServlet3 and CXFServlet4
servlet declarations. Note that CXFServlet4 registers a model containing interfaces so it
also registers a BookStoreNoAnnotationsImpl service class.</p>

<p>The workaround is to create a custom servlet :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class JAXRSUserModelServlet <span
class="code-keyword">extends</span> CXFNonSpringJaxrsServlet  {

@Override
<span class="code-keyword">public</span> void loadBus(ServletConfig servletConfig)
<span class="code-keyword">throws</span> ServletException {

<span class="code-keyword">super</span>.loadBus(servletConfig);

JAXRSServerFactoryBean sf = <span class="code-keyword">new</span> JAXRSServerFactoryBean();
<span class="code-object">String</span> address = servletConfig.getInitParameter(SERVICE_ADDRESS_PARAM);
<span class="code-comment">//jaxrs.address
</span><span class="code-keyword">if</span> (address == <span class="code-keyword">null</span>)
{
address = <span class="code-quote">"/"</span>;
}
sf.setAddress(address);

<span class="code-comment">// modelRef needs to start from 'classpath:', ex 'classpath:/WEB-INF/models/model1.xml
</span><span class="code-object">String</span> modelRef = servletConfig.getInitParameter(<span
class="code-quote">"user.model"</span>);
sf.setModelRef(modelRef);
sf.create();
}
</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+Advanced+Features">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=24190907&revisedVersion=3&originalVersion=2">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+Advanced+Features?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message