第 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
端口)。-
例如,作为绝对 URL mvapich- iwl 例如
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 命名空间
要在蓝图中定义 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 registry 上的
getBean ()
获取 bean 时,创建一个新的 bean 实例。 Request (请求)
- (仅在 Web 感知容器中可用) 为 bean 上调用的每个请求创建一个新的 bean 实例。
会话
- (只在 Web 感知容器中可用) 在单个 HTTP 会话的生命周期中创建一个新的 bean。
globalSession
- (仅在 Web 感知容器中可用) 为 portlet 之间共享的单一 HTTP 会话的生命周期创建一个新的 bean。
有关 Spring 范围的更多详情,请参阅有关 Bean 范围的 Spring 框架文档。
请注意,如果您通过 jaxrs:serviceBeans
元素指定 JAX-RS 资源 Bean,则 Spring 范围 无法正常工作。如果您在此例中指定资源 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 列表。
为获得理想的灵活性,您可以选择在配置 JAX-RS 服务器端点时,使用 jaxrs:serviceFactories
元素定义服务工厂对象。这种更加详细的方法具有将默认服务工厂实施替换为您的自定义实现的优势,从而为您提供对 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 文档关联了服务器端点,并且您希望在传入的信息中启用模式验证,您可以指定相关的 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)定义。 -
transport ID- 要选择 JMS 传输,
transportId
属性必须设置为http://cxf.apache.org/transports/jms
。 -
JMS address-
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 请求时,它会自动创建一个新的 accept 语言标头,其值为 en-gb
,并从资源 URL 剥离 .en
后缀。
18.1.2. jaxrs:server Attributes
属性
表 18.1 “JAX-RS 服务器端点属性” 描述 jaxrs:server
元素上可用的属性。
属性 | 描述 |
---|---|
| 指定其他配置元素可用于引用端点的唯一标识符。 |
| 指定 HTTP 端点的地址。这个值将覆盖服务合同中指定的值。 |
| (仅限Spring) 通过指定以逗号分隔的 Java 软件包列表来启用自动发现,这些 Java 软件包列表被搜索来发现 JAX-RS 根资源类和/或 JAX-RS 提供程序类。 |
|
指定 JAX-RS 根资源 Bean 的 bean ID 列表。在 Spring XML 的上下文中,可以通过在 root 资源 |
| 指定服务使用的消息绑定的 ID。第 23 章 Apache CXF 绑定 ID 中提供了有效绑定 ID 列表。 |
| 指定配置用于管理服务端点总线的 Spring bean 的 ID。这在将多个端点配置为使用一组常用功能时很有用。 |
| 指定外部 WADL 文档的位置。 |
|
将模型模式指定为 classpath 资源(例如,格式为 |
|
指定是否应自动发布该服务。如果设置为 |
|
指定 URL 基础地址,它插入到自动生成的 WADL 接口的 |
|
(仅限Spring) 在 Spring 中指定自动发现的服务注解类名称。当与 |
|
指定 JAX-RS root 资源类的名称(实施 JAX-RS 服务)。在这种情况下,该类由 Apache CXF 实例化,而不是按 Blueprint 或 Spring 进行实例化。如果要实例化 Blueprint 或 Spring 中的类,请使用 |
|
在特殊情况下,为 JAX-RS 端点指定 service QName (使用格式 |
|
如果为 |
|
用于选择非标准传输层(代替 HTTP)。特别是,您可以通过将此属性设置为 |
|
(仅限Spring) 指定是否 bean 是抽象 Bean。抽象 Bean 充当 concrete bean 定义的父项,且不会实例化。默认值为 |
| (仅限Spring) 指定端点在可实例化端点前实例化的 Bean 列表。 |
18.1.3. jaxrs:server Child Elements
子元素
表 18.2 “JAX-RS 服务器端点 Child Elements” 描述 jaxrs:server
元素的子元素。
元素 | 描述 |
---|---|
|
指定用于该服务的 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 根资源生命周期的最大控制程度。此元素的子项(必须是 |
| 指定与端点一起传递的属性的 Spring 映射。这些属性可用于控制诸如启用 MTOM 支持等功能。 |
|
此元素的子项是( |
|
包含对一个或多个 |
|
直接在此端点中定义资源模型(即,此 |
|
允许您将一个或多个自定义 JAX-RS 提供程序注册到此端点。此元素的子项是( |
|
当 REST 调用的 URL 以文件扩展名结尾时,您可以使用此元素将它自动与特定的内容类型关联。例如, |
|
当 REST 调用的 URL 以语言后缀结尾时,您可以使用此元素映射到特定语言。例如, |
|
指定用于验证 XML 消息内容的一个或多个 XML 模式。此元素可以包含一个或多个 |
| 允许您注册自定义资源比较器,它实现了与特定资源类或方法匹配的传入 URL 路径的算法。 |
|
如果要从类名称 创建多个资源,则只能使用 |
[a]
Invoker 实现控制如何调用服务。例如,它控制每个请求是否由服务实施的新实例处理,还是在调用之间保留状态。
|