Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

 

 

 

 

 

Span
stylefont-size:2em;font-weight:bold
JAX-RS : Advanced Features
 

 

 

 

 

Table of Contents

JMS Support

...

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:

Code Block
xml
xml

<jaxrs:server serviceName="s:BookService" transportId="http://cxf.apache.org/transports/jms" address="/">
 <jaxrs:serviceBeans>
   <bean class="org.apache.cxf.systest.jaxrs.JMSBookStore"/>
 </jaxrs:serviceBeans>
</jaxrs:server>

Additionally, JMS queue or topic configuration needs to be done, for example, please see this beans.xml. Please note how a serviceName attribute is used to specify a service QName for a jaxrs endpoint (default is {http://reverse.package.name}ServiceClassName), this service name is
used to configure a jms destination.

...

Starting from CXF 2.5.5 and CXF 2.6.2 it is possible to use the client proxies to invoke on JMS endpoints. All one needs to do is to provide a JMS endpoint address and then continue working with the proxy as usual. For example:

Code Block
java
java

// setup the the client
String endpointAddressUrlEncoded = "jms:jndi:dynamicQueues/test.jmstransport.text"
             + "?jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory"
             + "&replyToName=dynamicQueues/test.jmstransport.response"
             + "&jndiURL=tcp://localhost:" + JMS_PORT
             + "&jndiConnectionFactoryName=ConnectionFactory";
               
JMSBookStore client = JAXRSClientFactory.create(endpointAddressUrlEncoded, JMSBookStore.class);
Book book = client.getBook("123");
assertEquals("Get a wrong response code.", 200, WebClient.client(client).getResponse().getStatus());
assertEquals("Get a wrong book id.", 123, book.getId());

...

For example, the only thing you need to do to interpose Ehcache-Web on top of CXF JAX-RS endpoints is to add the following declarations to the web.xml, assuming the name of the war is 'ehcache-cxf':

Code Block
xml
xml

<context-param>
        <param-name>webAppRootKey</param-name>
        <param-value>ehcache-cxf</param-value>
    </context-param>
<filter>
        <filter-name>SimplePageCachingFilter</filter-name>
        <filter-class>net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter</filter-class>
        <init-param>
            <param-name>varyHeader</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>SimplePageCachingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Please see the Ehcache-Web page for more information on how to configure it, here is one example:

Code Block
xml
xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="../../main/config/ehcache.xsd"
    updateCheck="false"
    monitoring="autodetect"
    dynamicConfig="true">
	
	<defaultCache
		maxElementsInMemory="10"
		eternal="false"
		timeToIdleSeconds="5"
		timeToLiveSeconds="10"
		overflowToDisk="true" />
	
    <cache name="SimplePageCachingFilter"
		maxElementsInMemory="100"
		eternal="false"
		overflowToDisk="false"
		timeToIdleSeconds="5"
		timeToLiveSeconds="10"
        memoryStoreEvictionPolicy="LFU" />
</ehcache>

...

Here is an example :

Code Block
xml
xml

<model xmlns="http://cxf.apache.org/jaxrs">
  <resource name="org.apache.cxf.systest.jaxrs.BookStoreNoAnnotations" path="bookstore"
    produces="application/json" consumes="application/json">
    <operation name="getBook" verb="GET" path="/books/{id}" produces="application/xml">
       <param name="id" type="PATH"/>
    </operation>
    <operation name="getBookChapter" path="/books/{id}/chapter">
       <param name="id" type="PATH"/>
    </operation>
    <operation name="updateBook" verb="PUT">
       <param name="book" type="REQUEST_BODY"/>
    </operation>
  </resource>
  <resource name="org.apache.cxf.systest.jaxrs.ChapterNoAnnotations">
    <operation name="getItself" verb="GET"/>
    <operation name="updateChapter" verb="PUT" consumes="application/xml">
        <param name="content" type="REQUEST_BODY"/>
    </operation>
  </resource>
</model>

...

You can also register a model programmatically, for example :

Code Block
java
java

JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
            sf.setAddress("http://localhost:9080/");
String modelRef = "classpath:/org/apache/cxf/systest/jaxrs/resources/resources2.xml";
sf.setModelRef(modelRef);

// or if you have interface classes described in the model already loaded, ex : OSGI
// sf.setModelRefWithServiceClass(modelRef, BookStoreNoAnnotationsInterface.class);

// register an actual bean only if the model describes interfaces
sf.setServiceBeans(new BookStoreNoAnnotationsImpl());

...

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

Code Block
java
java

JAXRSClientFactoryBean cf = new JAXRSClientFactoryBean();
cf.setAddress("http://localhost:9080/");
String modelRef = "classpath:/org/apache/cxf/systest/jaxrs/resources/resources2.xml";
sf.setModelRef(modelRef);
BookStoreNoAnnotations proxy = cf.create(BookStoreNoAnnotations.class);

...

The workaround is to create a custom servlet :

Code Block
java
java

public class JAXRSUserModelServlet extends CXFNonSpringJaxrsServlet  {

@Override
public void loadBus(ServletConfig servletConfig) throws ServletException {

super.loadBus(servletConfig);

JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
String address = servletConfig.getInitParameter(SERVICE_ADDRESS_PARAM); //jaxrs.address
if (address == null) {
address = "/";
}
sf.setAddress(address);

// modelRef needs to start from 'classpath:', ex 'classpath:/WEB-INF/models/model1.xml
String modelRef = servletConfig.getInitParameter("user.model");
sf.setModelRef(modelRef);
sf.create();
}