Chapter 16. Configuring JAX-RS Endpoints
Abstract
This chapter explains how to instantiate and configure JAX-RS server endpoints in Blueprint XML and in Spring XML, and also how to instantiate and configure JAX-RS client endpoints (client proxy beans) in XML
16.1. Configuring JAX-RS Server Endpoints
16.1.1. Defining a JAX-RS Server Endpoint
Basic server endpoint definition
To define a JAX-RS server endpoint in XML, you need to specify at least the following:
- A
jaxrs:server
element, which is used to define the endpoint in XML. Note that thejaxrs:
namespace prefix maps to different namespaces in Blueprint and in Spring respectively. - The base URL of the JAX-RS service, using the
address
attribute of thejaxrs:server
element. Note that there are two different ways of specifying the address URL, which affects how the endpoint gets deployed:- As a relative URL—for example,
/customers
. In this case, the endpoint is deployed into the default HTTP container, and the endpoint's base URL is implicitly obtained by combining the CXF servlet base URL with the specified relative URL.For example, if you deploy a JAX-RS endpoint to the JBoss Fuse container, the specified/customers
URL would get resolved to the URL,http://Hostname:8181/cxf/customers
(assuming that the container is using the default8181
port). - As an absolute URL—for example,
http://0.0.0.0:8200/cxf/customers
. In this case, a new HTTP listener port is opened for the JAX-RS endpoint (if it is not already open). For example, in the context of JBoss Fuse, a new Jetty container would implicitly be created to host the JAX-RS endpoint. The special IP address,0.0.0.0
, acts as a wildcard, matching any of the hostnames assigned to the current host (which can be useful on multi-homed host machines).
- One or more JAX-RS root resource classes, which provide the implementation of the JAX-RS service. The simplest way to specify the resource classes is to list them inside a
jaxrs:serviceBeans
element.
Blueprint example
The following Blueprint XML example shows how to define a JAX-RS endpoint, which specifies the relative address,
/customers
(so that it deploys into the default HTTP container) and is implemented by the service.CustomerService
resource class:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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>
Blueprint XML namespaces
To define a JAX-RS endpoint in Blueprint, you typically require at least the following XML namespaces:
Prefix | Namespace |
---|---|
(default) | http://www.osgi.org/xmlns/blueprint/v1.0.0 |
cxf | http://cxf.apache.org/blueprint/core |
jaxrs | http://cxf.apache.org/blueprint/jaxrs |
Spring example
The following Spring XML example shows how to define a JAX-RS endpoint, which specifies the relative address,
/customers
(so that it deploys into the default HTTP container) and is implemented by the service.CustomerService
resource class:
<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"> <jaxrs:server id="customerService" address="/customers"> <jaxrs:serviceBeans> <ref bean="serviceBean"/> </jaxrs:serviceBeans> </jaxrs:server> <bean id="serviceBean" class="service.CustomerService"/> </beans>
Spring XML namespaces
To define a JAX-RS endpoint in Spring, you typically require at least the following XML namespaces:
Prefix | Namespace |
---|---|
(default) | http://www.springframework.org/schema/beans |
cxf | http://cxf.apache.org/core |
jaxrs | http://cxf.apache.org/jaxrs |
Auto-discovery in Spring XML
(Spring only) Instead of specifying the JAX-RS root resource classes explicitly, Spring XML enables you to configure auto-discovery, so that specific Java packages are searched for resource classes (classes annotated by
@Path
) and all of the discovered resource classes are automatically attached to the endpoint. In this case, you need to specify just the address
attribute and the basePackages
attribute in the jaxrs:server
element.
For example, to define a JAX-RS endpoint which uses all of the JAX-RS resource classes under the
a.b.c
Java package, you can define the endpoint in Spring XML, as follows:
<jaxrs:server address="/customers" basePackages="a.b.c"/>
The auto-discovery mechanism also discovers and installs into the endpoint any JAX-RS provider classes that it finds under the specified Java packages.
Lifecycle management in Spring XML
(Spring only) Spring XML enables you to control the lifecycle of beans by setting the
scope
attribute on a bean
element. The following scope values are supported by Spring:
singleton
- (Default) Creates a single bean instance, which is used everywhere and lasts for the entire lifetime of the Spring container.
prototype
- Creates a new bean instance every time the bean is injected into another bean or when a bean is obtained by invoking
getBean()
on the bean registry. request
- (Only available in a Web-aware container) Creates a new bean instance for every request invoked on the bean.
session
- (Only available in a Web-aware container) Creates a new bean for the lifetime of a single HTTP session.
globalSession
- (Only available in a Web-aware container) Creates a new bean for the lifetime of a single HTTP session that is shared between portlets.
For more details about Spring scopes, please consult the Spring framework documentation on Bean scopes.
Note that Spring scopes do not work properly, if you specify JAX-RS resource beans through the
jaxrs:serviceBeans
element. If you specify the scope
attribute on the resource beans in this case, the scope
attribute is effectively ignored.
In order to make bean scopes work properly within a JAX-RS server endpoint, you require a level of indirection that is provided by a service factory. The simplest way to configure bean scopes is to specify resource beans using the
beanNames
attribute on the jaxrs:server
element, as follows:
<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>
Where the preceding example configures two resource beans,
customerBean1
and customerBean2
. The beanNames
attribute is specified as a space-separated list of resource bean IDs.
For the ultimate degree of flexibility, you have the option of defining service factory objects explicitly, when you configure the JAX-RS server endpoint, using the
jaxrs:serviceFactories
element. This more verbose approach has the advantage that you can replace the default service factory implementation with your custom implementation, thus giving you ultimate control over the bean lifecycle. The following example shows how to configure the two resource beans, customerBean1
and customerBean2
, using this approach:
<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>
Note
If you specify a non-singleton lifecycle, it is often a good idea to implement and register a
org.apache.cxf.service.Invoker
bean (where the instance can be registered by referencing it from a jaxrs:server/jaxrs:invoker
element).
Attaching a WADL document
You can optionally associate a WADL document with the JAX-RS server endpoint using the
docLocation
attribute on the jaxrs:server
element. For example:
<jaxrs:server address="/rest" docLocation="wadl/bookStore.wadl"> <jaxrs:serviceBeans> <bean class="org.bar.generated.BookStore"/> </jaxrs:serviceBeans> </jaxrs:server>
Schema validation
If you have some external XML schemas, for describing message content in JAX-B format, you can associate these external schemas with the JAX-RS server endpoint through the
jaxrs:schemaLocations
element.
For example, if you have associated the server endpoint with a WADL document and you also want to enable schema validation on incoming messages, you can specify associated XML schema files as follows:
<jaxrs:server address="/rest" docLocation="wadl/bookStore.wadl"> <jaxrs:serviceBeans> <bean class="org.bar.generated.BookStore"/> </jaxrs:serviceBeans> <jaxrs:schemaLocations> <jaxrs:schemaLocation>classpath:/schemas/a.xsd</jaxrs:schemaLocation> <jaxrs:schemaLocation>classpath:/schemas/b.xsd</jaxrs:schemaLocation> </jaxrs:schemaLocations> </jaxrs:server>
Alternatively, if you want to include all of the schema files,
*.xsd
, in a given directory, you can just specify the directory name, as follows:
<jaxrs:server address="/rest" docLocation="wadl/bookStore.wadl"> <jaxrs:serviceBeans> <bean class="org.bar.generated.BookStore"/> </jaxrs:serviceBeans> <jaxrs:schemaLocations> <jaxrs:schemaLocation>classpath:/schemas/</jaxrs:schemaLocation> </jaxrs:schemaLocations> </jaxrs:server>
Specifying schemas in this way is generally useful for any kind of functionality that requires access to the JAX-B schemas.
Specifying the data binding
You can use the
jaxrs:dataBinding
element to specify the data binding that encodes the message body in request and reply messages. For example, to specify the JAX-B data binding, you could configure a JAX-RS endpoint as follows:
<jaxrs:server id="jaxbbook" address="/jaxb"> <jaxrs:serviceBeans> <ref bean="serviceBean" /> </jaxrs:serviceBeans> <jaxrs:dataBinding> <bean class="org.apache.cxf.jaxb.JAXBDataBinding"/> </jaxrs:dataBinding> </jaxrs:server>>
Or to specify the Aegis data binding, you could configure a JAX-RS endpoint as follows:
<jaxrs:server id="aegisbook" address="/aegis"> <jaxrs:serviceBeans> <ref bean="serviceBean" /> </jaxrs:serviceBeans> <jaxrs:dataBinding> <bean class="org.apache.cxf.aegis.databinding.AegisDatabinding"> <property name="aegisContext"> <bean class="org.apache.cxf.aegis.AegisContext"> <property name="writeXsiTypes" value="true"/> </bean> </property> </bean> </jaxrs:dataBinding> </jaxrs:server>
Using the JMS transport
It is possible to configure JAX-RS to use a JMS messaging library as a transport protocol, instead of HTTP. Because JMS itself is not a transport protocol, the actual messaging protocol depends on the particular JMS implementation that you configure.
For example, the following Spring XML example shows how to configure a JAX-RS server endpoint to use the JMS transport protocol:
<?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:jms="http://cxf.apache.org/transports/jms" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xsi:schemaLocation=" http://cxf.apache.org/transports/jms http://cxf.apache.org/schemas/configuration/jms.xsd 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"> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/> <bean id="ConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:${testutil.ports.EmbeddedJMSBrokerLauncher}" /> </bean> <jaxrs:server xmlns:s="http://books.com" serviceName="s:BookService" transportId= "http://cxf.apache.org/transports/jms" address="jms:queue:test.jmstransport.text?replyToName=test.jmstransport.response"> <jaxrs:serviceBeans> <bean class="org.apache.cxf.systest.jaxrs.JMSBookStore"/> </jaxrs:serviceBeans> </jaxrs:server> </beans>
Note the following points about the preceding example:
- JMS implementation—the JMS implementation is provided by the
ConnectionFactory
bean, which instantiates an Apache ActiveMQ connection factory object. After you instantiate the connection factory, it is automatically installed as the default JMS implementation layer. - JMS conduit or destination object—Apache CXF implicitly instantiates a JMS conduit object (to represent a JMS consumer) or a JMS destination object (to represent a JMS provider). This object must be uniquely identified by a QName, which is defined through the attribute setttings
xmlns:s="http://books.com"
(defining the namespace prefix) andserviceName="s:BookService"
(defining the QName). - Transport ID—to select the JMS transport, the
transportId
attribute must be set tohttp://cxf.apache.org/transports/jms
. - JMS address—the
jaxrs:server/@address
attribute uses a standardized syntax to specify the JMS queue or JMS topic to send to. For details of this syntax, see https://tools.ietf.org/id/draft-merrick-jms-uri-06.txt.
Extension mappings and language mappings
A JAX-RS server endpoint can be configured so that it automatically maps a file suffix (appearing in the URL) to a MIME content type header, and maps a language suffix to a language type header. For example, consider a HTTP request of the following form:
GET /resource.xml
You can configure the JAX-RS server endpoint to map the
.xml
suffix automatically, as follows:
<jaxrs:server id="customerService" address="/"> <jaxrs:serviceBeans> <bean class="org.apache.cxf.jaxrs.systests.CustomerService" /> </jaxrs:serviceBeans> <jaxrs:extensionMappings> <entry key="json" value="application/json"/> <entry key="xml" value="application/xml"/> </jaxrs:extensionMappings> </jaxrs:server>
When the preceding server endpoint receives the HTTP request, it automatically creates a new content type header of type,
application/xml
, and strips the .xml
suffix from the resource URL.
For the language mapping, consider a HTTP request of the following form:
GET /resource.en
You can configure the JAX-RS server endpoint to map the
.en
suffix automatically, as follows:
<jaxrs:server id="customerService" address="/"> <jaxrs:serviceBeans> <bean class="org.apache.cxf.jaxrs.systests.CustomerService" /> </jaxrs:serviceBeans> <jaxrs:languageMappings> <entry key="en" value="en-gb"/> </jaxrs:languageMappings> </jaxrs:server>
When the preceding server endpoint receives the HTTP request, it automatically creates a new accept language header with the value,
en-gb
, and strips the .en
suffix from the resource URL.
16.1.2. jaxrs:server Attributes
Attributes
Table 16.1, “JAX-RS Server Endpoint Attributes” describes the attributes available on the
jaxrs:server
element.
Attribute | Description |
---|---|
id | Specifies a unique identifier that other configuration elements can use to refer to the endpoint. |
address | Specifies the address of an HTTP endpoint. This value will override the value specified in the services contract. |
basePackages | (Spring only) Enables auto-discovery, by specifying a comma-separated list of Java packages, which are searched to discover JAX-RS root resource classes and/or JAX-RS provider classes. |
beanNames | Specifies a space-separated list of bean IDs of JAX-RS root resource beans. In the context of Spring XML, it is possible to define a root resource beans' lifecycle by setting the scope attribute on the root resource bean element. |
bindingId | Specifies the ID of the message binding the service uses. A list of valid binding IDs is provided in Appendix C, Apache CXF Binding IDs. |
bus | Specifies the ID of the Spring bean configuring the bus used to manage the service endpoint. This is useful when configuring several endpoints to use a common set of features. |
docLocation | Specifies the location of an external WADL document. |
modelRef | Specifies a model schema as a classpath resource (for example, a URL of the form classpath:/path/to/model.xml ). For details of how to define a JAX-RS model schema, see Section 16.3, “Defining REST Services with the Model Schema”. |
publish | Specifies if the service should be automatically published. If set to false , the developer must explicitly publish the endpoint. |
publishedEndpointUrl | Specifies the URL base address, which gets inserted into the wadl:resources/@base attribute of the auto-generated WADL interface. |
serviceAnnotation | (Spring only) Specifies the service annotation class name for auto-discovery in Spring. When used in combination with the basePackages property, this option restricts the collection of auto-discovered classes to include only the classes that are annotated by this annotation type.
|
serviceClass | Specifies the name of a JAX-RS root resource class (which implements a JAX-RS service). In this case, the class is instantiated by Apache CXF, not by Blueprint or Spring. If you want to instantiate the class in Blueprint or Spring, use the jaxrs:serviceBeans child element instead. |
serviceName | Specifies the service QName (using the format ns:name ) for the JAX-RS endpoint in the special case where a JMS transport is used. For details, see the section called “Using the JMS transport”. |
staticSubresourceResolution | If true , disables dynamic resolution of static sub-resources. Default is false . |
transportId | For selecting a non-standard transport layer (in place of HTTP). In particular, you can select the JMS transport by setting this property to http://cxf.apache.org/transports/jms . For details, see the section called “Using the JMS transport”. |
abstract | (Spring only) Specifies if the bean is an abstract bean. Abstract beans act as parents for concrete bean definitions and are not instantiated. The default is false . Setting this to true instructs the bean factory not to instantiate the bean. |
depends-on | (Spring only) Specifies a list of beans that the endpoint depends on being instantiated before the endpoint can be instantiated. |
16.1.3. jaxrs:server Child Elements
Child elements
Table 16.2, “JAX-RS Server Endpoint Child Elements” describes the child elements of the
jaxrs:server
element.
Element | Description |
---|---|
jaxrs:executor | Specifies a Java Executor (thread pool implementation) that is used for the service. This is specified using an embedded bean definition. |
jaxrs:features | Specifies a list of beans that configure advanced features of Apache CXF. You can provide either a list of bean references or a list of embedded beans. |
jaxrs:binding | Not used. |
jaxrs:dataBinding | Specifies the class implementing the data binding used by the endpoint. This is specified using an embedded bean definition. For more details, see the section called “Specifying the data binding”. |
jaxrs:inInterceptors | Specifies a list of interceptors that process inbound requests. For more information see Part VII, “Developing Apache CXF Interceptors”. |
jaxrs:inFaultInterceptors | Specifies a list of interceptors that process inbound fault messages. For more information see Part VII, “Developing Apache CXF Interceptors”. |
jaxrs:outInterceptors | Specifies a list of interceptors that process outbound replies. For more information see Part VII, “Developing Apache CXF Interceptors”. |
jaxrs:outFaultInterceptors | Specifies a list of interceptors that process outbound fault messages. For more information see Part VII, “Developing Apache CXF Interceptors”. |
jaxrs:invoker | Specifies an implementation of the org.apache.cxf.service.Invoker interface used by the service. [a] |
jaxrs:serviceFactories | Provides you with the maximum degree of control over the lifecycle of the JAX-RS root resources associated with this endpoint. The children of this element (which must be instances of org.apache.cxf.jaxrs.lifecycle.ResourceProvider type) are used to create JAX-RS root resource instances. |
jaxrs:properties | Specifies a Spring map of properties that are passed along to the endpoint. These properties can be used to control features like enabling MTOM support. |
jaxrs:serviceBeans | The children of this element are instances of (bean element) or references to (ref element) JAX-RS root resources. Note that in this case the scope attribute (Spring only), if present in the bean element, is ignored. |
jaxrs:modelBeans | Consists of a list of references to one or more org.apache.cxf.jaxrs.model.UserResource beans, which are the basic elements of a resource model (corresponding to jaxrs:resource elements). For details, see Section 16.3, “Defining REST Services with the Model Schema”. |
jaxrs:model | Defines a resource model directly in this endpoint (that is, this jaxrs:model element can contain one or more jaxrs:resource elements). For details, see Section 16.3, “Defining REST Services with the Model Schema”. |
jaxrs:providers | Enables you to register one or more custom JAX-RS providers with this endpoint. The children of this element are instances of (bean element) or references to (ref element) JAX-RS providers. |
jaxrs:extensionMappings | When the URL of a REST invocation ends in a file extension, you can use this element to associate it automatically with a particular content type. For example, the .xml file extension could be associated with the application/xml content type. For details, see the section called “Extension mappings and language mappings”. |
jaxrs:languageMappings | When the URL of a REST invocation ends in a language suffix, you can use this element to map this to a particular language. For example, the .en language suffix could be associated with the en-GB language. For details, see the section called “Extension mappings and language mappings”. |
jaxrs:schemaLocations | Specifies one or more XML schemas used for validating XML message content. This element can contain one or more jaxrs:schemaLocation elements, each specifying the location of an XML schema file (usually as a classpath URL). For details, see the section called “Schema validation”. |
jaxrs:resourceComparator | Enables you to register a custom resource comparator, which implements the algorithm used to match an incoming URL path to a particular resource class or method. |
jaxrs:resourceClasses | (Blueprint only) Can be used instead of the jaxrs:server/@serviceClass attribute, if you want to create multiple resources from class names. The children of jaxrs:resourceClasses must be class elements with a name attribute set to the name of the resource class. In this case, the classes are instantiated by Apache CXF, not by Blueprint or Spring. |
[a]
The Invoker implementation controls how a service is invoked. For example, it controls whether each request is handled by a new instance of the service implementation or if state is preserved across invocations.
|