第 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 中分别映射到 不同的命名空间。 JAX-RS 服务的基本 URL 使用
jaxrs:server
元素的address
属性。请注意,可以指定地址 URL 的方法有两种,这会影响如何部署端点:作为相对 URL- 例如:
/customers
.在这种情况下,端点会部署到默认 HTTP 容器中,并通过将 CXF servlet 基本 URL 与指定的相对 URL 合并来隐式获取端点的基本 URL。例如,如果您将 JAX-RS 端点部署到 Fuse 容器,指定的
/customers
URL 将解析为 URL,http://Hostname:8181/cxf/customers
(假设容器使用默认的8181
端口)。-
例如
http://0.0.0.0:8200/cxf/customers
,作为绝对 URL PlacementBinding-SOURCE。在本例中,为 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 容器中),并由 service.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 中的自动发现
(仅Spring) 用来显式指定 JAX-RS 根资源类,Spring XML 可让您配置自动发现,以便搜索具体的 Java 软件包(由 @Path
标注的类)以及所有发现的资源类都自动附加到端点。在这种情况下,您只需要在 jaxrs:server
元素中指定 address
属性和 basePackages
属性。
例如,要定义一个 JAX-RS 端点,它使用 a.b.c
Java 软件包下的所有 JAX-RS 资源类,您可以在 Spring XML 中定义端点,如下所示:
<jaxrs:server address="/customers" basePackages="a.b.c"/>
自动发现机制也会发现并安装到端点(在指定的 Java 软件包下找到的 JAX-RS 提供程序类)。
Spring XML 中的生命周期管理
(仅Spring) Spring XML 允许您通过设置 bean
元素上的 scope
属性来控制 Bean 的生命周期。Spring 支持以下范围值:
singleton
- (默认) 创建单个 bean 实例,它在 Spring 容器的整个生命周期内使用并持续使用。
prototype
-
每次将 bean 注入到另一 bean 时,或通过调用 bean 注册表的
getBean ()
来创建一个新的 Bean 实例。 request
- (只在 Web 感知容器中可用) 为每个在 bean 上调用的每个请求创建一个新的 Bean 实例。
会话
- (只在 Web 感知容器中可用) 在单个 HTTP 会话的生命周期中创建一个新的 Bean。
globalSession
- (只在 Web 感知容器中可用) 在 portlets 之间共享的单个 HTTP 会话生命周期中创建一个新的 Bean。
如需有关 Spring 范围的详细信息,请参阅 Bean 范围的 Spring 框架文档。
请注意,如果通过 jaxrs:serviceBeans
元素指定 JAX-RS 资源 Bean,则 Spring 范围 无法正常工作。如果您在此例中指定 resource Bean 的 scope
属性,则有效忽略 scope
属性。
要使 bean 范围在 JAX-RS 服务器端点内正常工作,您需要一系列由服务工厂提供的间接化。配置 Bean 范围最简单的方法是,使用 jaxrs:server
元素中的 beanNames
属性来指定资源 Bean,如下所示:
<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、client Bean1
和 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 文档关联,并且您希望在传入消息中启用模式验证,您可以指定关联的 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 提供程序类。 |
|
指定 JAX-RS 根资源 Bean 的 bean ID 空格分隔的列表。在 Spring XML 上下文中,可以通过设置 root 资源 bean 元素的 |
| 指定服务使用的消息绑定 ID。第 23 章 Apache CXF Binding ID 中提供了有效绑定 ID 列表。 |
| 指定 Spring bean 配置用于管理服务端点的总线的 ID。这在将多个端点配置为使用一组通用的功能时很有用。 |
| 指定外部 WADL 文档的位置。 |
|
将模型模式指定为类路径资源(例如,格式为 |
|
指定是否应自动发布该服务。如果设置为 |
|
指定 URL 基本地址,它被插入到自动生成的 WADL 接口的 |
|
(仅Spring) 指定 Spring 中自动发现的服务注解类名称。与 |
|
指定 JAX-RS 根资源类(实施 JAX-RS 服务)的名称。在这种情况下,该类由 Apache CXF 进行实例化,而不是由 Blueprint 或 Spring 进行实例化。如果要在 Blueprint 或 Spring 中实例化类,请使用 |
|
在特殊情况下,在使用 JMS 传输时指定 JAX-RS 端点的 service QName (使用 |
|
如果为 |
|
选择非标准传输层(代替 HTTP)。特别是,您可以通过将此属性设置为 |
|
(仅 Spring) 如果 bean 是一个抽象 bean,则指定。抽象 bean 作为 concrete bean 定义的父项,它们不会被实例化。默认值为 |
| (仅Spring) 指定端点依赖在端点实例化前实例化的 Bean 列表。 |
18.1.3. jaxrs:server Child Elements
子元素
表 18.2 “JAX-RS 服务器端点子元素” 描述 jaxrs:server
元素的子元素。
element | 描述 |
---|---|
|
指定用于该服务的 Java |
| 指定配置 Apache CXF 高级功能的 Bean 列表。您可以提供 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 root 资源生命周期的最大控制程度。此元素的子项(必须是 |
| 指定传递给端点的属性的 Spring 映射。这些属性可用于控制启用 MTOM 支持等功能。 |
|
此元素的子项是( |
|
由一个或多个 |
|
在此端点中直接定义资源模型(即,此 |
|
允许您将一个或多个自定义 JAX-RS 提供程序注册到此端点。此元素的子项是 ( |
|
当 REST 调用的 URL 以文件扩展结尾时,您可以使用这个元素自动将其与特定内容类型关联。例如, |
|
当 REST 调用的 URL 以语言后缀结尾时,您可以使用此元素将它映射到特定的语言。例如, |
|
指定用于验证 XML 消息内容的一个或多个 XML 模式。此元素可以包含一个或多个 |
| 允许您注册自定义资源比较器,它实施用于匹配特定资源类或方法的传入 URL 路径的算法。 |
|
(仅限蓝色打印) 如果想要从类名称创建多个资源,而不使用 |
[a]
Invoker 实施控制如何调用服务。例如,它控制每个请求是否由服务实施的新实例处理,或者是否在调用期间保留状态。
|