...
Span | ||||
---|---|---|---|---|
| =
| |||
} JAX-RS : Services Configuration {span} {toc} h1. Configuring Configuration |
Table of Contents |
---|
Configuring JAX-RS
...
services
...
programmatically
Code Block | ||||
---|---|---|---|---|
| ||||
{code:java} import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; ... JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean(); sf.setResourceClasses(CustomerService.class); sf.setAddress("http://localhost:9000/"); sf.create(); {code} |
Some
...
things
...
to
...
note:
...
- The
...
- JAXRSServerFactoryBean
...
- creates
...
- a
...
- Server
...
- inside
...
- CXF
...
- which
...
- starts
...
- listening
...
- for
...
- requests
...
- on
...
- the
...
- URL
...
- specified.
...
- Check
...
- the
...
...
- API for methods for adding multiple root resources
- setResourceClasses() is for root resources only, use setProvider() or setProviders() for @Provider-annotated classes.
By default, the JAX-RS runtime is responsible for the lifecycle of resource classes, default lifecycle is per-request. You can set the lifecycle to singleton by using following line:
Code Block java java sf.setResourceProvider(BookStore.class, new SingletonResourceProvider(new BookStore()));
...
If you prefer not to let the JAX-RS
...
runtime
...
handle
...
the
...
resource
...
class
...
lifecycle
...
for
...
you
...
(for
...
example,
...
it
...
might
...
be
...
the
...
case
...
that
...
your
...
resource
...
class
...
is
...
created
...
by
...
other
...
containers
...
such
...
as
...
Spring),
...
you
...
can
...
do
...
the
...
following:
...
Code Block java java JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean(); CustomerService cs = new CustomerService(); sf.setServiceBeans(cs); sf.setAddress("http://localhost:9080/"); sf.create();
OSGI
Blueprint
The following example shows how to configure a JAX-RS endpoint in OSGI containers supporting Blueprint:
Code Block | ||||
---|---|---|---|---|
| ||||
{code} h1. OSGI h2. Blueprint The following example shows how to configure a JAX-RS endpoint in OSGI containers supporting Blueprint: {code:xml} <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws" xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs" xmlns:cxf="http://cxf.apache.org/blueprint/core" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd "> <cxf:bus> <cxf:features> <cxf:logging/> </cxf:features> </cxf:bus> <jaxrs:server id="customerService" address="/customers"> <jaxrs:serviceBeans> <ref component-id="serviceBean" /> </jaxrs:serviceBeans> </jaxrs:server> <bean id="serviceBean" class="service.CustomerService"/> </blueprint> {code} h2. Spring {code:xml} |
Spring
Code Block | ||||
---|---|---|---|---|
| ||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/osgi/cxf-extension-osgi.xml" /> <jaxrs:server id="customerService" address="/customers"> <jaxrs:serviceBeans> <ref bean="serviceBean"/> </jaxrs:serviceBeans> </jaxrs:server> <bean id="serviceBean" class="service.CustomerService"/> </beans> {code} h1. Configuring JAX-RS endpoints programmatically without Spring Note that even though no Spring is explicitly used in the previous section, it is still used by default |
Spring Boot
Please see CXF SpringBoot documentation.
Please see JAX-RS Spring Boot and JAX-RS Spring Boot Scan demos.
Please see JAXRSClientSpringBoot documentation on how CXF JAX-RS Clients can be used in a SpringBoot Application.
Configuring JAX-RS endpoints programmatically without Spring
Note that even though no Spring is explicitly used in the previous section, it is still used by default to have various CXF components registered with the bus such as transport factories. If no Spring libraries are available on the classpath then please follow the following example :
Code Block | ||||
---|---|---|---|---|
| ||||
to have various CXF components registered with the bus such as transport factories. If no Spring libraries are available on the classpath then please follow the following example :
{code:java}
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
sf.setResourceClasses(CustomerService.class);
sf.setResourceProvider(CustomerService.class, new SingletonResourceProvider(new CustomerService()));
sf.setAddress("http://localhost:9000/");
BindingFactoryManager manager = sf.getBus().getExtension(BindingFactoryManager.class);
JAXRSBindingFactory factory = new JAXRSBindingFactory();
factory.setBus(sf.getBus());
manager.registerBindingFactory(JAXRSBindingFactory.JAXRS_BINDING_ID, factory);
sf.create();
|
Blueprint Web
This section describes how CXF JAX-RS endpoints can be bootstrapped with CXFBlueprintServlet and Blueprint contexts.
This approach is recommended for developers building CXF JAX-RS endpoints to be deployed in OSGI and which will do RequestDispatcher-based forwards.
Additionally it allows to reuse the same Blueprint contexts between OSGI and non-OSGI deployments.
Both options below work with CXF 3.1.3:
Code Block | ||||
---|---|---|---|---|
| ||||
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.1.3</version>
</dependency>
|
Maven dependencies
OSGI
Code Block | ||||
---|---|---|---|---|
| ||||
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.webosgi</artifactId>
<version>1.0.1</version>
</dependency>
|
In OSGI (Karaf) one should also install a 'war' feature.
Servlet Container
Code Block | ||||
---|---|---|---|---|
| ||||
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.web</artifactId>
<version>1.1.1</version>
</dependency>
|
Common example
This web.xml shows how to setup CXFBlueprintServlet which processes this Blueprint context. It works exactly the same way in OSGI and non-OSGI environments.
Configuring JAX-RS services in container with Spring configuration file.
web.xml
In web.xml one needs to register one or more CXFServlet(s) and link to an application context configuration.
Using Spring ContextLoaderListener
Code Block | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/beans.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
|
The application context configuration is shared between all the CXFServlets
Using CXFServlet init parameters
Code Block | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>CXFServlet1</servlet-name> <display-name>CXF Servlet1</display-name> <servlet-class> org.apache.cxf.transport.servlet.CXFServlet </servlet-class> <init-param> {code} h1. Configuring JAX-RS services in container with Spring configuration file. h2. web.xml In web.xml one needs to register one or more CXFServlet(s) and link to an application context configuration. h3. Using Spring ContextLoaderListener {code:xml} <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <context-param> <param-name>contextConfigLocation</param-name> <param-value>WEB-INF/beans.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <servlet> <servlet-name>CXFServlet</servlet-name> <display-name>CXF Servlet</display-name> <servlet-class> org.apache.cxf.transport.servlet.CXFServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app> {code} The application context configuration is shared between all the CXFServlets h3. Using CXFServlet init parameters {code:xml} <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>CXFServlet1</servlet-name> <display-name>CXF Servlet1</display-name> <servlet-class> org.apache.cxf.transport.servlet.CXFServlet </servlet-class> <init-param> <param-name>config-location</param-name> <param-value>/WEB-INF/beans1.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>CXFServlet2</servlet-name> <display-name>CXF Servlet2</display-name> <servlet-class> org.apache.cxf.transport.servlet.CXFServlet </servlet-class> <init-param> <param-name>config-location</param-name> <param-value>/WEB-INF/beans2.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet1</servlet-name> <url-pattern>/1/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>CXFServlet2</servlet-name> <url-pattern>/2/*</url-pattern> </servlet-mapping> </web-app> {code} |
Each
...
CXFServlet
...
can
...
get
...
a
...
unique
...
application
...
context
...
configuration.
...
Note,
...
no
...
Spring
...
ContextLoaderListener
...
is
...
registered
...
in
...
web.xml
...
in
...
this
...
case.
...
beans.xml
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml} <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> <!-- do not use import statements if CXFServlet init parameters link to this beans.xml --> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <jaxrs:server id="customerService" address="/service1"> <jaxrs:serviceBeans> <ref bean="customerBean" /> </jaxrs:serviceBeans> </jaxrs:server> <bean id="customerBean" class="demo.jaxrs.server.CustomerService" /> </beans> {code} |
In
...
the
...
above
...
configuration
...
all
...
resources
...
will
...
be
...
configured
...
as
...
singletons,
...
see
...
...
for
...
information
...
on
...
creating
...
per-request
...
resources.
...
Configuring JAX-RS
...
services
...
using
...
explicit
...
bean
...
configuration
...
Note
...
that
...
jaxrs:server
...
(and
...
jaxrs:client)
...
declarations
...
depend
...
on
...
'http://cxf.apache.org/jaxrs'
...
Spring
...
NamespaceHandler
...
be
...
available
...
on
...
classpath.
...
Sometimes,
...
due
...
to
...
classloading
...
restrictions
...
or
...
bugs
...
in
...
underlying
...
containers
...
which
...
are
...
exposed
...
during
...
complex
...
deployments
...
or
...
due
...
to
...
multiple
...
Spring
...
libraries
...
interfering
...
with
...
each
...
other,
...
NamespaceHandler
...
can
...
not
...
be
...
located
...
and
...
thus
...
jaxrs
...
endpoints
...
can
...
not
...
be
...
created.
...
Please
...
report
...
such
...
issues
...
to
...
the
...
team
...
working
...
on
...
developing
...
the
...
container
...
itself.
...
If
...
you
...
need
...
to
...
do
...
Spring
...
configuration
...
and
...
get
...
an
...
error
...
to
...
do
...
with
...
a
...
missing
...
NamespaceHandler
...
then,
...
as
...
a
...
workaround,
...
consider
...
configuring
...
jaxrs
...
endpoints
...
using
...
CXF
...
beans
...
which
...
actually
...
handle
...
the
...
creation
...
of
...
jaxrs:server
...
endpoints.
...
This
...
is
...
marginally
...
more
...
complex,
...
but
...
overall,
...
the
...
configuration
...
ends
...
up
...
being
...
quite
...
similar,
...
for
...
example,
...
the
...
above
...
jaxrs:server
...
endpoint
...
can
...
be
...
configured
...
like
...
this
...
instead:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml} <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <bean class="org.apache.cxf.jaxrs.JAXRSServerFactoryBean" init-method="create"> <property name="address" value="/service1"/> <property:serviceBeans> name="serviceBeans"> <ref bean="customerBean" /> </property:serviceBeans>property> </jaxrs:server>bean> <bean id="customerBean" class="demo.jaxrs.server.CustomerService" /> </beans> {code} h1. Spring AOP CXF |
Spring AOP
CXF JAX-RS
...
is
...
capable
...
of
...
working
...
with
...
AOP
...
interceptors
...
applied
...
to
...
resource
...
classes
...
from
...
Spring.
...
For
...
example:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml} <beans xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml"/> <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml"/> <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> <jaxrs:server id="bookservice" address="/"> <jaxrs:serviceBeans> <ref bean="bookstore"/> <ref bean="bookstoreInterface"/> </jaxrs:serviceBeans> </jaxrs:server> <bean id="bookstore" class="org.apache.cxf.systest.jaxrs.BookStore"/> <bean id="bookstoreInterface" class="org.apache.cxf.systest.jaxrs.BookStoreWithInterface"/> <aop:config> <aop:aspect id="loggingAspect" ref="simpleLogger"> <aop:before method="logBefore" pointcut="execution(* org.apache.cxf.systest.jaxrs.BookStore*.*(..))"/> <aop:after-returning method="logAfter" pointcut="execution(* org.apache.cxf.systest.jaxrs.BookStore*.*(..))"/> </aop:aspect> </aop:config> <bean id="simpleLogger" class="org.apache.cxf.systest.jaxrs.SimpleLoggingAspect"/> </beans> {code} Note that some AOP configuration is applied to two |
Note that some AOP configuration is applied to two JAX-RS
...
resource
...
classes.
...
By
...
default
...
Spring
...
uses
...
JDK
...
dynamic
...
proxies
...
if
...
a
...
class
...
to
...
be
...
proxified
...
implements
...
at
...
least
...
one
...
interface
...
or
...
CGLIB
...
proxies
...
otherwise.
...
For
...
example,
...
here's
...
how
...
org.apache.cxf.systest.jaxrs.BookStoreWithInterface
...
looks
...
like:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:java} public interface BookInterface { @GET @Path("/thosebooks/{bookId}/") @Produces("application/xml") Book getThatBook(Long id) throws BookNotFoundFault; } public class BookStoreWithInterface extends BookStoreStorage implements BookInterface { public Book getThatBook(@PathParam("bookId") Long id) throws BookNotFoundFault { return doGetBook(id); } @Path("/thebook") public Book getTheBook(@PathParam("bookId") Long id) throws BookNotFoundFault { return doGetBook(id); } } {code} |
In
...
this
...
case
...
Spring
...
will
...
use
...
a
...
JDK
...
dynamic
...
proxy
...
to
...
wrap
...
a
...
BookStoreWithInterface
...
class.
...
As
...
such
...
it
...
is
...
important
...
that
...
the
...
method
...
which
...
needs
...
to
...
be
...
invoked
...
such
...
as
...
getThatBook(...)
...
will
...
be
...
part
...
of
...
the
...
interface.
...
The
...
other
...
method,
...
getTheBook()
...
can
...
not
...
be
...
dispatched
...
to
...
by
...
a
...
JAX-RS
...
runtime
...
as
...
it's
...
not
...
possible
...
to
...
discover
...
it
...
through
...
a
...
JDK
...
proxy.
...
If
...
this
...
method
...
also
...
needs
...
to
...
be
...
invoked
...
then
...
this
...
method
...
should
...
either
...
be
...
added
...
to
...
the
...
interface
...
or
...
CGLIB
...
proxies
...
have
...
to
...
be
...
explicitly
...
enabled
...
(consult
...
Spring
...
AOP
...
documentation
...
for
...
more
...
details).
...
For
...
example:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml} <aop:config proxy-target-class="true"/> {code} h1. Configuring |
Configuring JAX-RS
...
services
...
in
...
container
...
without
...
Spring
...
If
...
you
...
prefer,
...
you
...
can
...
register
...
JAX-RS
...
endpoints
...
without
...
depending
...
on
...
Spring
...
with
...
the
...
help
...
of
...
CXFNonSpringJaxrsServlet
...
:
Code Block | ||||
---|---|---|---|---|
| ||||
:xml} <servlet> <servlet-name>CXFServlet</servlet-name> <display-name>CXF Servlet</display-name> <servlet-class> org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet </servlet-class> <init-param> <param-name>jaxrs.serviceClasses</param-name> <param-value> org.apache.cxf.systest.jaxrs.BookStore1, org.apache.cxf.systest.jaxrs.BookStore2 </param-value> </init-param> <init-param> <param-name>jaxrs.providers</param-name> <param-value> org.apache.cxf.systest.jaxrs.BookStoreProvider1, org.apache.cxf.systest.jaxrs.BookStoreProvider2 </param-value> </init-param> <!-- enables schema validation --> <init-param> <param-name>jaxrs.schemaLocations</param-name> <param-value> classpath:/WEB-INF/schemas/schema1.xsd classpath:/WEB-INF/schemas/schema2.xsd </param-value> </init-param> <!-- registers CXF in interceptors --> <init-param> <param-name>jaxrs.inInterceptors</param-name> <param-value> org.apache.cxf.systest.jaxrs.CustomInInterceptor </param-value> </init-param> <!-- registers CXF out interceptors --> <init-param> <param-name>jaxrs.outInterceptors</param-name> <param-value> org.apache.cxf.systest.jaxrs.CustomOutInterceptor </param-value> </init-param> <!-- registers extension mappings --> <init-param> <param-name>jaxrs.extensions</param-name> <param-value> xml=application/xml json=application/json </param-value> </init-param> <!-- registers contextual properties --> <init-param> <param-name>jaxrs.properties</param-name> <param-value> property1=value property2=value </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> {code} When service classes and providers are registered this way, the default life-cycle is |
When service classes and providers are registered this way, the default life-cycle is 'singleton'.
...
You
...
can
...
override
...
it
...
by
...
setting
...
a
...
"jaxrs.scope"
...
parameter
...
with
...
the
...
value
...
of
...
'prototype'
...
(equivalent
...
to
...
per-request).
...
By
...
default,
...
the
...
endpoint
...
address
...
is
...
"/".
...
One
...
can
...
provide
...
a
...
more
...
specific
...
value
...
using
...
a
...
"jaxrs.address" parameter.
Note that multiple service or providers class names are separated by a comma. Users may want to use a "class.parameter.split.char" servlet parameter with the value "space" when
migrating from the older CXF versions were the space was used to separate multiple class names.
If the referenced service classes are not annotated with JAX-RS annotations then an external user model can also be linked to :
Code Block | ||||
---|---|---|---|---|
| ||||
parameter. If the referenced service classes are not annotated with JAX-RS annotations then an external user model can also be linked to : {code:xml} <servlet> <servlet-name>CXFServlet</servlet-name> <display-name>CXF Servlet</display-name> <servlet-class> org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet </servlet-class> <init-param> <param-name>jaxrs.serviceClasses</param-name> <param-value> org.apache.cxf.systest.jaxrs.BookStore </param-value> </init-param> <!-- link to the user model --> <init-param> <param-name>user.model</param-name> <param-value> classpath:/models/resources.xml </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> {code} |
A
...
more
...
portable
...
way
...
to
...
register
...
resource
...
classes
...
and
...
providers
...
with
...
CXFNonSpringJaxrsServlet
...
is
...
to
...
use
...
a
...
JAX-RS
...
Application
...
Code Block | ||||
---|---|---|---|---|
| ||||
<servlet> <servlet-name>CXFServlet</servlet-|http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookApplication.java] : {code:xml} <servlet> <servlet-name>CXFServlet</servlet-name> <display-name>CXF Servlet</display-name> <servlet-class> org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet </servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value> org.apache.cxf.systest.jaxrs.BookApplication </param-value> </init-param> <!-- This parameter is recognized only starting from CXF 2.3.1 @ApplicationPath value will be ignored if this parameter is set to true --> <init-param> <param-name>jaxrs.application.address.ignore</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> {code} |
Note
...
that
...
Application.getClasses()
...
method
...
returns
...
a
...
set
...
of
...
per-request
...
resource
...
class
...
names.
...
Application.getSingletons()
...
returns
...
a
...
list
...
of
...
singleton
...
resource
...
and
...
provider
...
classes.
...
Starting
...
from
...
CXF
...
2.3.7/2.4.3/2.5.0
...
it
...
is
...
possible
...
to
...
simple
...
properties
...
for
...
resource
...
and
...
Application
...
classes,
...
providers
...
and
...
interceptors:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml} <servlet> <servlet-name>CXFServlet</servlet-name> <display-name>CXF Servlet</display-name> <servlet-class> org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet </servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value> org.apache.cxf.systest.jaxrs.BookApplication (name=1 id=2) </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> {code} |
In
...
the
...
above
...
example,
...
org.apache.cxf.systest.jaxrs.BookApplication
...
is
...
expected
...
to
...
have
...
setName
...
and
...
setId
...
setters,
...
with
...
a
...
single
...
primitive
...
or
...
List
...
parameter
...
type.
...
Note that having the web-app_2_3.dtd
...
DTD
...
referenced
...
from
...
web.xml
...
will
...
likely
...
prevent
...
'param-value'
...
containing
...
spaces
...
and
...
make
...
it
...
difficult
...
to
...
specify
...
multiple
...
providers
...
like
...
this:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml} <init-param> <param-name>jaxrs.providers</param-name> <param-value> mypackage.Provider1 mypackage.Provider2 </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> {code} |
In
...
such
...
cases
...
consider
...
moving
...
to
...
the
...
web-app
...
2.5
...
schema
...
or
...
extending
...
CXFNonSpringJaxrsProviders
...
or
...
introducing
...
an
...
Application.
Attaching JAXRS endpoints to an existing Jetty server
Here is a code fragment showing how it can be done with the help of CxfNonSpringJaxrsServlet :
Code Block | ||||
---|---|---|---|---|
| ||||
h2. Attaching JAXRS endpoints to an existing Jetty server Here is a code fragment showing how it can be done with the help of CxfNonSpringJaxrsServlet : {code:java} CXFNonSpringJAXRSServlet cxf = new CXFNonSpringJaxrsServlet(); ... ServletHolder servlet = new ServletHolder(cxf); servlet.setInitParameter("javax.ws.rs.Application", "com.acme.MyServiceImpl"); servlet.setName("services"); servlet.setForcedPath("services"); root.addServlet(servlet, "/*"); {code} h1. |
JAX-RS
...
RuntimeDelegate
...
and
...
Applications
...
If
...
you
...
have
...
a
...
JAX-RS
...
Application
...
implementation
...
available
...
and
...
would
...
like
...
to
...
minimize
...
the
...
interaction
...
with
...
the
...
CXF
...
JAX-RS
...
specific
...
API,
...
you
...
may
...
want
...
to
...
use
...
the
...
JAX-RS
...
RuntimeDelegate
...
:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:java} import javax.ws.rs.ext.RuntimeDelegate; import org.apache.cxf.endpoint.Server; import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; RuntimeDelegate delegate = RuntimeDelegate.getInstance(); JAXRSServerFactoryBean bean = delegate.createEndpoint(new CustomApplication(), JAXRSServerFactoryBean.class); // before CXF 2.3.1 : // bean.setAddress("http://localhost:8080/services"); bean.setAddress("http://localhost:8080/services" + bean.getAddress()); Server server = bean.create(); server.start(); // and finally server.stop(); {code} |
Note
...
that
...
the
...
above
...
code
...
makes
...
sure
...
an
...
@ApplicationPath
...
value
...
(if
...
CustomApplication
...
has
...
this
...
annotation)
...
is
...
taken
...
into
...
account.
...
Configuring
...
JAX-RS
...
services
...
programmatically
...
with
...
Spring
...
configuration
...
file.
...
When
...
using
...
Spring
...
explicitly
...
in
...
your
...
code,
...
you
...
may
...
want
...
to
...
follow
...
this
...
example
...
:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:java} ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(new String[] {"/org/apache/cxf/jaxrs/spring/servers.xml"}); // 'simple' is the id of the jaxrs server bean JAXRSServerFactoryBean sfb = (JAXRSServerFactoryBean)ctx.getBean("simple"); sfb.create(); {code} |
Note
...
that
...
in
...
in
...
this
...
case
...
your
...
Spring
...
configuration
...
file
...
should
...
import
...
cxf-extension-http-jetty.xml
...
instead
...
of
...
cxf-servlet.xml
...
:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml} <!-- <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> --> <import resource="classpath:META-INF/cxf/cxf-extension-http-jetty.xml" /> { |
Lifecycle management
From Spring
By default, the service beans which are referenced directly from the jaxrs:server endpoint declarations are treated by the runtime as singleton JAX-RS root resources. For example:
Code Block | ||||
---|---|---|---|---|
| ||||
code} h1. Lifecycle management h2. From Spring By default, the service beans which are referenced directly from the jaxrs:server endpoint declarations are treated by the runtime as singleton JAX-RS root resources. For example: {code:xml} <beans> <jaxrs:server id="customerService" address="/service1"> <jaxrs:serviceBeans> <ref bean="customerBean" /> </jaxrs:serviceBeans> </jaxrs:server> <!-- The scope attribute, if any, will be ignored. For example, adding the scope attribute with the value "request", "prototype", etc, won't have any effect, the customerBean will still be treated as a JAX-RS singleton by the runtime. --> <bean id="customerBean" class="demo.jaxrs.server.CustomerService" /> </beans> {code} |
Spring
...
instantiates
...
and
...
injects
...
the
...
customerBean
...
reference
...
and
...
the
...
runtime
...
will
...
access
...
this
...
reference
...
directly
...
afterwards.
...
Effectively,
...
the
...
scope
...
attribute
...
which
...
may
...
be
...
present
...
on
...
the
...
customerBean
...
bean
...
declaration
...
is
...
ignored
...
in
...
this
...
case,
...
unless
...
the
...
Spring
...
AOP
...
is
...
used
...
to
...
enforce
...
the
...
required
...
scope
...
(see
...
below
...
for
...
more
...
information).
...
The
...
'serviceFactories'
...
element
...
or
...
beanNames
...
attribute
...
has
...
to
...
be
...
used
...
for
...
a
...
'prototype',
...
'request'
...
and
...
other
...
Spring
...
bean
...
scopes
...
be
...
supported.
...
For
...
example,
...
the
...
serviceFactories
...
element
...
can
...
reference
...
one
...
or
...
more
...
beans
...
of
...
type
...
'org.apache.cxf.jaxrs.spring.SpringResourceFactory'
...
which
...
in
...
turn
...
reference
...
the
...
actual
...
service
...
beans.
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml} <beans> <jaxrs:server id="customerService" address="/service1"> <jaxrs:serviceFactories> <ref bean="sfactory1" /> <ref bean="sfactory2" /> </jaxrs:serviceFactories> </jaxrs:server> <bean id="sfactory1" class="org.apache.cxf.jaxrs.spring.SpringResourceFactory"> <property name="beanId" value="customerBean1"/> </bean> <bean id="sfactory2" class="org.apache.cxf.jaxrs.spring.SpringResourceFactory"> <property name="beanId" value="customerBean2"/> </bean> <bean id="customerBean1" class="demo.jaxrs.server.CustomerRootResource1" scope="prototype"/> <bean id="customerBean2" class="demo.jaxrs.server.CustomerRootResource2" scope="prototype"/> </beans> {code} |
In
...
this
...
example,
...
the
...
jaxrs:server
...
endpoint
...
has
...
two
...
JAX-RS
...
root
...
resources
...
(customerBean1
...
and
...
customerBean2)
...
with
...
the
...
Spring
...
'prototype'
...
scope.
...
Other
...
scopes
...
can
...
also
...
be
...
supported.
...
If
...
using
...
the
...
jaxrs:serviceFactories
...
element
...
seems
...
a
...
bit
...
verbose
...
then
...
the
...
'beanNames'
...
attribute
...
can
...
be
...
used
...
instead:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml} <beans> <jaxrs:server id="customerService" address="/service1" beanNames="customerBean1 customerBean2"/> <bean id="customerBean1" class="demo.jaxrs.server.CustomerRootResource1" scope="prototype"/> <bean id="customerBean2" class="demo.jaxrs.server.CustomerRootResource2" scope="prototype"/> </beans> {code} The beanNames attribute lists the |
The beanNames attribute lists the names/ids
...
of
...
service
...
beans
...
separated
...
by
...
space.
...
The
...
jaxrs:serviceFactories
...
element
...
has
...
to
...
be
...
used
...
when
...
users
...
register
...
custom
...
CXF
...
JAX-RS
...
...
implementations.
...
Another
...
approach
...
toward
...
supporting
...
complex
...
scopes
...
in
...
Spring
...
is
...
to
...
use
...
Spring
...
AOP.
...
For
...
example,
...
the
...
following
...
fragment
...
shows
...
how
...
to
...
have
...
the
...
Spring
...
"request"
...
scope
...
supported:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml} <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml"/> <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/> <jaxrs:server id="example" address="/"> <jaxrs:serviceBeans> <bean class="org.apache.cxf.systest.jaxrs.CustomerService" scope="request"><aop:scoped-proxy /></bean> </jaxrs:serviceBeans> </jaxrs:server> </beans> {code} |
in
...
addition,
...
the
...
following
...
servlet
...
listener
...
has
...
to
...
be
...
added
...
to
...
the
...
web.xml:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml} <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> {code} |
The
...
request-scoped
...
service
...
bean
...
instances
...
(example,
...
org.apache.cxf.systest.jaxrs.CustomerService
...
instances)
...
are
...
not
...
actually
...
available
...
at
...
the
...
initialization
...
time
...
thus
...
one
...
limitation
...
of
...
the
...
above
...
configuration
...
is
...
that
...
it
...
is
...
not
...
possible
...
to
...
inject
...
JAX-RS
...
contexts
...
into
...
these
...
service
...
beans.
...
This
...
is
...
not
...
a
...
show-stopper
...
because
...
contexts
...
such
...
as
...
UriInfo
...
can
...
be
...
passed
...
in
...
as
...
resource
...
method
...
parameters.
...
However,
...
if
...
the
...
injection
...
into
...
the
...
fields
...
or
...
via
...
method
...
setters
...
is
...
required
...
then
...
a
...
little
...
customization
...
of
...
the
...
org.apache.cxf.jaxrs.spring.SpringResourceFactory
...
will
...
do
...
the
...
trick.
...
Particularly,
...
the
...
Spring
...
ApplicationContext
...
reports
...
that
...
a
...
request-scoped
...
bean
...
is
...
a
...
singleton
...
but
...
the
...
JAX-RS
...
runtime
...
can
...
not
...
inject
...
thread-local
...
proxies
...
given
...
that
...
the
...
actual
...
instance
...
is
...
not
...
available
...
as
...
explained
...
above;
...
in
...
fact,
...
the
...
request-scoped
...
beans
...
are
...
not
...
really
...
JAX-RS
...
singletons.
...
Thus
...
a
...
simple
...
custom
...
factory
...
like
...
...
...
is
...
needed
...
and
...
it
...
has
...
to
...
be
...
used
...
the
...
following
...
way:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml} <beans> <jaxrs:server id="customerService" address="/service1"> <jaxrs:serviceFactories> <bean class="org.apache.cxf.systest.jaxrs.RequestScopeResourceFactory"> <property name="beanId" value="customerBean"/> </bean> </jaxrs:serviceFactories> </jaxrs:server> <bean id="customerBean" class="org.apache.cxf.systest.jaxrs.CustomerService" scope="request"><aop:scoped-proxy /></bean> </beans> {code} |
The
...
above
...
configuration
...
makes
...
sure
...
that
...
the
...
CXF
...
JAX-RS
...
runtime
...
injects
...
the
...
values
...
at
...
the
...
request
...
time
...
given
...
that
...
the
...
customerBean
...
bean
...
is
...
not
...
seen
...
as
...
a
...
JAX-RS
...
singleton.
...
This
...
approach
...
is
...
only
...
needed
...
if
...
the
...
injection
...
of
...
contexts
...
is
...
required.
...
With
...
CXFNonSpringJaxrsServlet
...
CXFNonSpringJaxrsServlet
...
uses
...
'Singleton'
...
as
...
a
...
default
...
scope
...
for
...
service
...
classes
...
specified
...
by
...
a
...
"jaxrs.serviceClasses"
...
servlet
...
parameter.
...
It
...
can
...
be
...
overridden
...
by
...
setting
...
a
...
"jaxrs.scope"
...
parameter
...
to
...
a
...
"prototype"
...
value
...
or
...
by
...
not
...
using
...
the
...
"jaxrs.serviceClasses"
...
parameter
...
at
...
all
...
and
...
registering
...
a
...
JAXRS
...
Application
...
implementation
...
instead.
...
Please
...
see
...
the
...
section
...
describing
...
CXFNonSpringJaxrsServlet
...
for
...
more
...
details.
...
CXFNonSpringJaxrsServlet
...
can
...
support
...
singleton
...
scopes
...
for
...
classes
...
with
...
constructors
...
expecting
...
JAXRS
...
contexts,
...
at
...
the
...
moment
...
it
...
can
...
only
...
inject
...
ServletContext
...
or
...
ServletConfig
...
contexts
...
:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:java}
@Path("/")
public class SingletonResourceClass {
public SingletonResourceClass(@Context ServletContext context, @Context ServletConfig context2) {}
}
|
Programmatically
Code Block | ||||
---|---|---|---|---|
| ||||
{code} h2. Programmatically {code:java} JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean(); sf.setResourceClass(CustomerService.class); sf.setResourceProvider(new SingletonResourceProvider(new CustomerService())); sf.setResourceClass(CustomerService2.class); sf.setResourceProvider(new PerRequestResourceProvider(CustomerService.class)); {code} h2. PostConstruct and PreDestroy Bean methods annotated with @PostConstruct and @PreDestroy annotations will be called as expected by the scope rules. Singleton beans will have their postconstruct method called when the endpoint is created. If a given singleton resource instance was created by Spring then its predestroy method will also be called after, for example, the web application which uses it is about to be unloaded. At the moment singletons created by CXFNonSpringJaxrsServlet or programmatically will only have their postconstruct method (if any) called. Prototype beans will have their postconstruct and predestroy method called before a resource method is invoked and immediately after the invocation has returned but before the response has actually been serialized. You can indicate that the predestroy method has to be called after the request has completely gone out of scope (that is after the response body if any has been written to the output stream) by adding an |
PostConstruct and PreDestroy
Bean methods annotated with @PostConstruct and @PreDestroy annotations will be called as expected by the scope rules.
Singleton beans will have their postconstruct method called when the endpoint is created. If a given singleton resource instance was created by Spring then its predestroy method will also be called after, for example, the web application which uses it is about to be unloaded. At the moment singletons created by CXFNonSpringJaxrsServlet or programmatically will only have their postconstruct method (if any) called.
Prototype beans will have their postconstruct and predestroy method called before a resource method is invoked and immediately after the invocation has returned but before the response has actually been serialized. You can indicate that the predestroy method has to be called after the request has completely gone out of scope (that is after the response body if any has been written to the output stream) by adding an "org.apache.cxf.
...
service.scope"
...
property
...
with
...
the
...
value
...
set
...
to
...
"request".
...
You
...
can
...
also
...
register
...
a
...
custom
...
Spring
...
resource
...
factory
...
by
...
extending
...
org.apache.cxf.jaxrs.spring.SpringResourceFactory
...
or
...
providing
...
a
...
more
...
sophisticated
...
implementation.
...
Locating
...
custom
...
resources
...
in
...
web
...
applications
...
Resources
...
like
...
schemas,
...
custom
...
XSLT
...
templates
...
and
...
user
...
models
...
are
...
typically
...
referenced
...
using
...
a
...
classpath:
...
prefix.
...
Thus
...
one
...
can
...
add
...
them
...
to
...
a
...
WEB-INF/classes
...
folder
...
in
...
a
...
given
...
web
...
application.
...
Since
...
CXF
...
2.2.3
...
one
...
can
...
put
...
them
...
directly
...
under
...
WEB-INF,
...
for
...
example
...
into
...
WEB-INF/xslt,
...
WEB-INF/schemas,
...
WEB-INF/model
...
and
...
referencing
...
them
...
like
...
'classpath:/WEB-INF/xslt/template.xsl'.
...
Multiple
...
endpoints
...
and
...
resource
...
classes
...
One
...
can
...
configure
...
as
...
many
...
jaxrs:server
...
endpoints
...
as
...
needed
...
for
...
a
...
given
...
application,
...
with
...
every
...
endpoint
...
possibly
...
providing
...
an
...
alternative
...
path
...
to
...
a
...
single
...
resource
...
bean.
...
Every
...
endpoint
...
can
...
employ
...
as
...
many
...
shared
...
or
...
unique
...
resource
...
classes
...
as
...
needed,
...
and
...
have
...
common
...
or
...
different
...
providers.
Sharing providers between multiple endpoints
One way to share multiple providers between multiple endpoints is to refer to the same provider bean from within jaxrs:provider sections:
Code Block | ||||
---|---|---|---|---|
| ||||
h1. Sharing providers between multiple endpoints One way to share multiple providers between multiple endpoints is to refer to the same provider bean from within jaxrs:provider sections: {code:xml} <beans> <jaxrs:server id="customerService" address="/service1"> <jaxrs:serviceBeans> <bean class="org.apache.cxf.systest.jaxrs.CustomerService"/> </jaxrs:serviceBeans> <jaxrs:providers> <bean ref="customProvider"/> </jaxrs:providers> </jaxrs:server> <jaxrs:server id="customerService" address="/service2"> <jaxrs:serviceBeans> <bean class="org.apache.cxf.systest.jaxrs.CustomerService2"/> </jaxrs:serviceBeans> <jaxrs:providers> <bean ref="customProvider"/> </jaxrs:providers> </jaxrs:server> <bean id="customProvider" class="org.apache.cxf.systest.jaxrs.CustomerProvider"/> </beans> {code} |
Starting
...
from
...
CXF
...
2.7.2
...
it
...
is
...
possible
...
to
...
register
...
provider
...
directly
...
on
...
the
...
bus
...
as
...
the
...
bus
...
properties
...
and
...
share
...
them
...
between
...
all
...
the
...
providers
...
using
...
this
...
bus:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml} <beans> <cxf:bus> <cxf:properties> <entry key="javax.ws.rs.ext.ExceptionMapper" value-ref="exceptionMapper"/> </cxf:properties> </cxf:bus <bean id="exceptionMapper" class="org.apache.cxf.systest.jaxrs.RuntimeExceptionMapper"/> <jaxrs:server id="customerService" address="/service1"> <jaxrs:serviceBeans> <bean class="org.apache.cxf.systest.jaxrs.CustomerService"/> </jaxrs:serviceBeans> </jaxrs:server> <jaxrs:server id="customerService" address="/service2"> <jaxrs:serviceBeans> <bean class="org.apache.cxf.systest.jaxrs.CustomerService2"/> </jaxrs:serviceBeans> </jaxrs:server> </beans> {code} |
Note
...
a
...
global
...
exception
...
mapper
...
has
...
been
...
registered
...
using
...
the
...
name
...
of
...
interface,
...
"javax.ws.rs.ext.ExceptionMapper",
...
which
...
all
...
the
...
exception
...
mappers
...
have
...
to
...
implement.
...
Note
...
that
...
once
...
can
...
register
...
global
...
per-bus
...
providers
...
using
...
"javax.ws.rs.ext.ExceptionMapper",
...
"javax.ws.rs.ext.MessageBodyReader"
...
or
...
"javax.ws.rs.ext.MessageBodyWriter"
...
bus
...
properties
...
with
...
the
...
registered
...
providers
...
expected to implement either of these interfaces.
Alternatively, one can have all the providers (JAX-RS and CXF-specific) registered with a bus using "org.apache.cxf.jaxrs.bus.providers" list property:
Code Block | ||||
---|---|---|---|---|
| ||||
<beans xmlns:util="http://www.springframework.org/schema/util">
<cxf:bus>
<cxf:properties>
<entry key="org.apache.cxf.jaxrs.bus.providers" value-ref="busProviders"/>
</cxf:properties>
</cxf:bus
<util:list id="busProviders">
<ref bean="exceptionMapper"/>
<ref bean="customMessageBodyReader"/>
<ref bean="customMessageBodyWriter"/>
</util:list>
<bean id="exceptionMapper" class="org.apache.cxf.systest.jaxrs.RuntimeExceptionMapper"/>
<bean id="customMessageBodyReader" class="org.apache.cxf.systest.jaxrs.CustomReader"/>
<bean id="customMessageBodyWriter" class="org.apache.cxf.systest.jaxrs.CustomWriter"/>
<jaxrs:server id="customerService" address="/service1">
<jaxrs:serviceBeans>
<bean class="org.apache.cxf.systest.jaxrs.CustomerService"/>
</jaxrs:serviceBeans>
</jaxrs:server>
<jaxrs:server id="customerService" address="/service2">
<jaxrs:serviceBeans>
<bean class="org.apache.cxf.systest.jaxrs.CustomerService2"/>
</jaxrs:serviceBeans>
</jaxrs:server>
</beans>
|
Dynamic servlets and a single JAX-RS endpoint
Note: this is not required by default starting from CXF 3.0.0-milestone1
In some advanced cases you may want to dynamically add new servlets (CXFServlet or CXFNonSpringJaxrsServlet) with all of them serving the same JAX-RS endpoints. In this case you most likely want to configure servlets so that the CXF endpoint address is not overridden :
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml}
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<init-param>
<param-name>config-location</param-name>
<param-value>/WEB-INF/beans1.xml</param-value>
</init-param>
<init-param>
<param-name>disable-address-updates</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
|
Auto-discovery of root resources and providers
Starting from CXF 3.0.0 it is possible to enable the auto-discovery of JAX-RS roots and providers with the regular CXF JAX-RS endpoint declarations done in XML . Currently it is only possible with Spring. Patch supporting it for Blueprint is available and will be dealt with asap.
Spring
Code Block | ||||
---|---|---|---|---|
| ||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xsi:schemaLocation=" to implement either of these interfaces. Alternatively, one can have all the providers (JAX-RS and CXF-specific) registered with a bus using "org.apache.cxf.jaxrs.bus.providers" list property: {code:xml} <beans xmlns:util="http://www.springframework.org/schema/util"> beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd <cxf:bus> <cxf:properties>http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> <entry key="org.apache.cxf.jaxrs.bus.providers" ref="busProviders"<import resource="classpath:META-INF/cxf/cxf.xml" /> </cxf:properties> </cxf:bus !-- <util:list id="busProviders"> <ref bean="exceptionMapper"/> <ref bean="customMessageBodyReader"/> <ref bean="customMessageBodyWriter"/> </util:list> <bean id="exceptionMapper" class="org.apache.cxf.systest.jaxrs.RuntimeExceptionMapper"/> <bean id="customMessageBodyReader" class="org.apache.cxf.systest.jaxrs.CustomReader"/> <bean id="customMessageBodyWriter" class="org.apache.cxf.systest.jaxrs.CustomWriter"/> <jaxrs:server id="customerService" address="/service1"> <jaxrs:serviceBeans> Discover all root resources and providers in packages starting from "a.b.c" --> <jaxrs:server address="/customers" basePackages="a.b.c"/> <!-- Discover a root resource and providers in packages starting from "a.b.c" and "d.e.f", Note that in case of jaxrs:client, having multiple discoverable root resources can lead to <bean class="org.apache.cxf.systest.jaxrs.CustomerService"/> </jaxrs:serviceBeans> </jaxrs:server> <jaxrs:server id="customerService" address="/service2"> unexpected results, as only the single root can be recognized <jaxrs:serviceBeans> --> <bean class="org.apache.cxf.systest.jaxrs.CustomerService2<jaxrs:client address="http://customers" basePackages="a.b.c,d.e.f"/> </jaxrs:serviceBeans> </jaxrs:server> </beans> {code} h1. Dynamic servlets and a single JAX-RS endpoint Note: this is not required by default starting from CXF 3.0.0-milestone1 In some advanced cases you may want to dynamically add new servlets (CXFServlet or CXFNonSpringJaxrsServlet) with all of them serving the same JAX-RS endpoints. In this case you most likely want to configure servlets so that the CXF endpoint address is not overridden : {code:xml} {code:xml} <servlet> <servlet-name>CXFServlet</servlet-name> <display-name>CXF Servlet</display-name> <servlet-class> org.apache.cxf.transport.servlet.CXFServlet </servlet-class> <init-param> <param-name>config-location</param-name> <param-value>/WEB-INF/beans1.xml</param-value> </init-param> <init-param> <param-name>disable-address-updates</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> {code} {code} h1. Servlet and Application Container Configuration Please see this [page|https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+Deployment] for more information. </beans> |
Note the above does not require Spring annotations such as @Component added to JAX-RS provider or resources.
If you prefer doing a pure Spring-based auto-discovery you can have @Component added to JAX-RS application classes and do
Code Block | ||||
---|---|---|---|---|
| ||||
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<!--
Discover all root resources and providers in packages starting from "a.b.c"
-->
<jaxrs:server address="/customers"/>
<context:component-scan base-package="a.b.c"/>
</beans>
|
Servlet and Application Container Configuration
Please see this page for more information.
Starting from CXF 3.1.0: org.apache.cxf.jaxrs.servlet.sci.JaxrsServletContainerInitializer implementing javax.servlet.ServletContainerInitializer is shipped in a cxf-rt-rs-http-sci module.
Adding this module will support no-web.xml and other JAX-RS deployments depending on the container auto-discovery mechanism as described in a 2.3.2 section of JSR-339 (JAX-RS 2.0).