第 18 章 配置 JAX-RS 端点
摘要
本章论述了如何在 Blueprint XML 和 Spring XML 中实例化和配置 JAX-RS 服务器端点,以及如何在 XML 中实例化和配置 JAX-RS 客户端端点(客户端代理 Bean)
18.1. 配置 JAX-RS 服务器端点
18.1.1. 定义 JAX-RS 服务器端点
基本服务器端点定义
要在 XML 中定义 JAX-RS 服务器端点,您需要至少指定以下内容:
-
jaxrs:server
元素,用于定义 XML 中的端点。请注意,jaxrs:
命名空间前缀分别映射到 Blueprint 和 Spring 中的不同命名空间。 使用
jaxrs:server
元素的地址属性的 JAX-RS 服务的基本 URL。请注意,有两种不同的方法来指定地址 URL,这会影响端点的部署方式:
作为相对 URL- 例如:
/customers
。在本例中,端点被部署到默认的 HTTP 容器中,通过将 CXF servlet 基本 URL 与指定的相对 URL 相结合,端点的基本 URL 会被隐式获得。例如,如果您将 JAX-RS 端点部署到 Fuse 容器,则指定的
/customers
URL 将解析为 URLhttp://Hostname:8181/cxf/customers
(假设容器使用默认的8181
端口)。-
作为绝对 URL 10.10.10.2-sHistoryLimit,例如
http://0.0.0.0:8200/cxf/customers
。在本例中,为 JAX-RS 端点打开一个新的 HTTP 侦听器端口(如果尚未打开)。例如,在 Fuse 上下文中,会隐式创建新的 Undertow 容器以托管 JAX-RS 端点。特殊的 IP 地址0.0.0.0
充当通配符,匹配分配给当前主机的任何主机名(对于多设备主机机器很有用)。
-
一个或多个 JAX-RS 根资源类,提供 JAX-RS 服务的实施。指定资源类的最简单方法是在
jaxrs:serviceBeans
元素内列出它们。
蓝图示例
以下 Blueprint XML 示例演示了如何定义 JAX-RS 端点,该端点指定相对地址 /customers
(因此将其部署到默认 HTTP 容器)并由 service.CustomerService
资源类实施:
<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 https://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>
蓝图 XML 命名空间
要在 Blueprint 中定义 JAX-RS 端点,通常需要以下 XML 命名空间:
prefix | 命名空间 |
---|---|
(默认) | |
| |
|
Spring 示例
以下 Spring XML 示例演示了如何定义 JAX-RS 端点,用于指定相对地址 /customers
(因此将其部署到默认 HTTP 容器)并由 服务实施。CustomerService
资源类:
<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 命名空间
要在 Spring 中定义 JAX-RS 端点,通常需要以下 XML 命名空间:
prefix | 命名空间 |
---|---|
(默认) | |
| |
|
Spring XML 中的自动发现
(仅) 明确指定 JAX-RS 根资源类,Spring XML 可让您配置自动发现,以便搜索特定 Java 软件包以获取资源类(由 @Path
标注的类),并且所有发现的资源类都自动附加到端点。在这种情况下,您需要在 jaxrs:server
元素中仅指定 address
属性和 basePackages
属性。
例如,若要定义使用 a.b.c
Java 软件包下的所有 JAX-RS 资源类的 JAX-RS 端点,您可以在 Spring XML 中定义端点,如下所示:
<jaxrs:server address="/customers" basePackages="a.b.c"/>
自动发现机制还会发现并安装到端点,在其在指定的 Java 软件包下找到的任何 JAX-RS 提供程序类。
Spring XML 中的生命周期管理
(仅限 Spring XML) 通过设置 bean
元素上的 scope
属性来控制 Bean 的生命周期。Spring 支持以下范围值:
单例
- (默认) 创建一个单个 bean 实例,该实例在 Spring 容器的整个生命周期中使用。
prototype
-
每次将 bean 注入到另一个 bean 或 bean 获取 bean 时,或通过调用 bean registry 上的
getBean()
来新建一个 bean 实例。 Request(请求)
- (仅适用于 Web 感知型容器) 为 Bean 上调用的每个请求创建一个新的 bean 实例。
session
- (只在一个 Web 感知容器中可用) 为单个 HTTP 会话生命周期创建一个新 Bean。
globalSession
- (只在一个 Web 感知容器中可用) 为在 portlet 之间共享的单个 HTTP 会话的生命周期创建一个新 Bean。
如需有关 Spring 范围的更多详细信息,请参阅有关 Bean 范围的 Spring 框架文档。
请注意,如果您通过 jaxrs:serviceBeans
元素指定 JAX-RS 资源 Bean,Spring 范围 无法正常工作。如果您在此例中指定 resource Bean 上的 scope
属性,则 scope
属性将有效忽略。
要让 bean 范围在 JAX-RS 服务器端点内正常工作,您需要一个由服务工厂提供的间接级别。配置 bean 范围的最简单方法是使用 jaxrs:server
元素上的 beanNames
属性来指定 resourceanNames 属性,如下所示:
<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>
上一示例配置两个资源 Bean,即 customerBean1
和 customerBean2
。beanNames
属性指定为空格分隔的资源 bean ID 列表。
为了获得灵活性,您可以 显式 定义服务工厂对象的选项,当您使用 jaxrs:serviceFactories
元素配置 JAX-RS 服务器端点时。这种更详细的方法有优势,您可以将默认服务工厂实施替换为您的自定义实施,从而让您最终掌控 bean 生命周期。以下示例演示了如何使用此方法配置两个资源 Bean、customerBean1
和 customerBean2
:
<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>
如果您指定了非单例生命周期,则通常最好实施和注册 org.apache.cxf.service.Invoker bean(其中,可以通过引用来自 jaxrs:server/jaxrs:invoker
元素来注册实例)。
附加 WADL 文档
您可以使用 jaxrs:server
元素上的 docLocation
属性,将 WADL 文档与 JAX-RS 服务器端点关联。例如:
<jaxrs:server address="/rest" docLocation="wadl/bookStore.wadl"> <jaxrs:serviceBeans> <bean class="org.bar.generated.BookStore"/> </jaxrs:serviceBeans> </jaxrs:server>
模式验证
如果您有一些外部 XML 模式,用于描述 JAX-B 格式的消息内容,您可以通过 jaxrs:schemaLocations
将这些外部模式与 JAX-RS 服务器端点关联。
例如,如果您已将服务器端点与 WADL 文档相关联,并且您希望在传入消息上启用 schema 验证,您可以按如下方式指定相关的 XML 架构文件:
<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>
或者,如果您要将所有模式文件( *.xsd
)包含在给定目录中,您可以只指定目录名称,如下所示:
<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>
以这种方式指定架构对于需要访问 JAX-B 模式的任何种类的功能通常有用。
指定数据绑定
您可以使用 jaxrs:dataBinding
元素指定在请求和回复消息中编码消息正文的数据绑定。例如,若要指定 JAX-B 数据的绑定,您可以配置 JAX-RS 端点,如下所示:
<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>>
或者指定 Aegis 数据的绑定,您可以按照如下所示配置 JAX-RS 端点:
<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>
使用 JMS 传输
可以将 JAX-RS 配置为将 JMS 消息库用作传输协议,而不使用 HTTP。由于 JMS 本身 不是 传输协议,因此实际的消息传递协议取决于您配置的特定 JMS 实施。
例如,以下 Spring XML 示例演示了如何配置 JAX-RS 服务器端点以使用 JMS 传输协议:
<?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>
请注意,以下有关上例的几点:
-
JMS 实施- JMS 实施由
ConnectionFactory
bean 提供,后者实例化 Apache ActiveMQ 连接工厂对象。在实例化连接工厂后,它会作为默认的 JMS 实现层自动安装。 -
JMS conduit 或 destination 对象-Apache CXF 隐式实例化 JMS conduit 对象(代表 JMS 消费者)或 JMS 目标对象(代表 JMS 提供程序)。这个对象必须由 QName 唯一标识,它通过 setttings
xmlns:s="http://books.com"
定义(定义命名空间前缀)和serviceName="s:BookService"(
定义 QName)。 -
传输 ID- 要选择 JMS 传输,
transportId
属性必须设置为http://cxf.apache.org/transports/jms
。 -
JMS 地址-
jaxrs:server/@address
属性使用标准化语法来指定要发送到的 JMS 队列或 JMS 主题。有关此语法的详情,请参考 https://tools.ietf.org/id/draft-merrick-jms-uri-06.txt。
扩展映射和语言映射
可以配置 JAX-RS 服务器端点,使它自动将文件后缀(在 URL 中应用)映射到 MIME 内容类型标头,并将语言后缀映射到语言类型标头。例如,考虑以下形式的 HTTP 请求:
GET /resource.xml
您可以配置 JAX-RS 服务器端点,以自动映射 .xml
后缀,如下所示:
<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>
当上述服务器端点收到 HTTP 请求时,它会自动创建类型为 application/xml
的新内容类型标头,并从资源 URL 剥离 .xml
后缀。
对于语言映射,请考虑以下格式的 HTTP 请求:
GET /resource.en
您可以配置 JAX-RS 服务器端点,以自动映射 .en
后缀,如下所示:
<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>
当上述服务器端点收到 HTTP 请求时,它会自动创建一个新的接受语言标头,值为 en-gb
,并从资源 URL 剥离 .en
后缀。
18.1.2. jaxrs:server 属性
属性
表 18.1 “JAX-RS 服务器端点属性” 描述 jaxrs:server
元素中可用的属性。
属性 | 描述 |
---|---|
| 指定其他配置元素可用于引用端点的唯一标识符。 |
| 指定 HTTP 端点的地址。这个值将覆盖服务合同中指定的值。 |
| (仅限 Spring) 启用自动发现功能,方法是指定以逗号分隔的 Java 软件包列表,这些列表用于发现 JAX-RS 根资源类和/或 JAX-RS 提供程序类。 |
|
指定 JAX-RS root 资源 Bean ID 的以空格分开的列表。在 Spring XML 上下文中,可以通过设置 root 资源 |
| 指定服务使用的消息绑定 ID。第 23 章 Apache CXF Binding ID 中提供了有效绑定 ID 列表。 |
| 指定 Spring Bean 的 ID,配置用于管理服务端点的总线。这在将多个端点配置为使用一组通用的功能时,这很有用。 |
| 指定外部 WADL 文档的位置。 |
|
将模型 schema 指定为类路径资源(例如,classpath |
|
指定是否应该自动发布该服务。如果设置为 |
|
指定 URL 基础地址,该地址将插入到自动生成的 WADL 接口的 |
|
(仅限 Spring) 指定 Spring 中自动发现的服务注解类名称。与 |
|
指定 JAX-RS 根资源类的名称(实施 JAX-RS 服务)。在这种情况下,类由 Apache CXF 进行实例化,而不是由 Blueprint 或 Spring 进行实例化。如果要在 Blueprint 或 Spring 中实例化类,请使用 |
|
指定在使用 JMS 传输的特殊情况下,为 JAX-RS 端点指定服务 QName(使用 |
|
如果为 |
|
用于选择非标准传输层(替换 HTTP)。特别是,您可以通过将此属性设置为 |
|
(仅限 Spring) 指定 bean 是否为抽象 bean。abstract Bean 充当拥塞 Bean 定义且没有实例化的父项。默认值为 |
| (Spring only) 指定端点在端点实例化之前要实例化的 Bean 列表,然后可以实例化该端点。 |
18.1.3. jaxrs:server Child Elements
子元素
表 18.2 “JAX-RS 服务器端点子元素” 描述 jaxrs:server
元素的子元素。
元素 | 描述 |
---|---|
|
指定用于该服务的 Java |
| 指定 Beans 列表,用于配置 Apache CXF 的高级功能。您可以提供 bean 引用列表或嵌入式 Bean 列表。 |
| 未使用. |
| 指定实施端点使用的数据绑定的类。这使用嵌入式 bean 定义进行指定。如需了解更多详细信息,请参阅 “指定数据绑定”一节。 |
| 指定处理入站请求的拦截器列表。更多信息请参阅 第 VII 部分 “开发 Apache CXF Interceptors”。 |
| 指定处理入站错误信息的拦截器列表。更多信息请参阅 第 VII 部分 “开发 Apache CXF Interceptors”。 |
| 指定处理出站回复的拦截器列表。更多信息请参阅 第 VII 部分 “开发 Apache CXF Interceptors”。 |
| 指定处理出站错误信息的拦截器列表。更多信息请参阅 第 VII 部分 “开发 Apache CXF Interceptors”。 |
| 指定服务使用的 org.apache.cxf.service.Invoker 接口的实施。[a] |
|
为您提供对与此端点关联的 JAX-RS 根资源的生命周期的最大控制程度。此元素的子项(必须是 |
| 指定传递给端点的属性的 Spring 映射。这些属性可用于控制启用 MTOM 支持等功能。 |
|
此元素的子项是(an 元素)的实例或引用( |
|
由一个或多个 |
|
在此端点中直接定义资源模型(即,这个 |
|
使您能够使用此端点注册一个或多个自定义 JAX-RS 提供程序。此元素的子项是(an 元素)的实例或引用( |
|
当 REST 调用的 URL 以文件扩展结尾时,您可以使用此元素将其与特定内容类型关联。例如, |
|
当 REST 调用的 URL 以语言后缀结尾时,您可以使用此元素将这个元素映射到特定的语言。例如, |
|
指定验证 XML 消息内容的一个或多个 XML 模式。此元素可以包含一个或多个 |
| 可让您注册自定义资源比较器,它实施用于匹配特定资源类或方法的传入 URL 路径的算法。 |
|
如果要从类名称创建多个资源,则只使用 |
[a]
Invoker 实施控制如何调用服务。例如,它控制每个请求是否由服务实施的新实例处理,或在调用中保留状态。
|