第 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 服务器端点,您需要至少指定以下内容:

  1. jaxrs:server 元素,用于在 XML 中定义端点。请注意,jaxrs: 命名空间前缀分别映射到 Blueprint 和 Spring 中的不同命名空间。
  2. 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 充当通配符,匹配分配给当前主机的任何主机名(这对于多重主机机器很有用)。
  3. 一个或多个 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命名空间

(默认)

http://www.osgi.org/xmlns/blueprint/v1.0.0

cxf

http://cxf.apache.org/blueprint/core

jaxrs

http://cxf.apache.org/blueprint/jaxrs

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命名空间

(默认)

http://www.springframework.org/schema/beans

cxf

http://cxf.apache.org/core

jaxrs

http://cxf.apache.org/jaxrs

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,即 customerBean1customerBean2beanNames 属性指定为以空格分隔的资源 bean ID 列表。

为获得理想的灵活性,您可以选择在配置 JAX-RS 服务器端点时,使用 jaxrs:serviceFactories 元素定义服务工厂对象。这种更加详细的方法具有将默认服务工厂实施替换为您的自定义实现的优势,从而为您提供对 bean 生命周期的最终控制。以下示例演示了如何配置两个资源 Bean,即 customerBean1customerBean2,使用此方法:

<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 元素上可用的属性。

表 18.1. JAX-RS 服务器端点属性
属性描述

id

指定其他配置元素可用于引用端点的唯一标识符。

address

指定 HTTP 端点的地址。这个值将覆盖服务合同中指定的值。

basePackages

(仅限Spring) 通过指定以逗号分隔的 Java 软件包列表来启用自动发现,这些 Java 软件包列表被搜索来发现 JAX-RS 根资源类和/或 JAX-RS 提供程序类。

beanNames

指定 JAX-RS 根资源 Bean 的 bean ID 列表。在 Spring XML 的上下文中,可以通过在 root 资源 bean 元素上设置 scope 属性来定义根资源 Bean 的生命周期。

bindingId

指定服务使用的消息绑定的 ID。第 23 章 Apache CXF 绑定 ID 中提供了有效绑定 ID 列表。

bus

指定配置用于管理服务端点总线的 Spring bean 的 ID。这在将多个端点配置为使用一组常用功能时很有用。

docLocation

指定外部 WADL 文档的位置。

modelRef

将模型模式指定为 classpath 资源(例如,格式为 classpath:/path/to/model.xml的 URL)。有关如何定义 JAX-RS 模型模式的详情,请参考 第 18.3 节 “使用 Model Schema 定义 REST 服务”

publish

指定是否应自动发布该服务。如果设置为 false,开发人员必须明确发布端点。

publishedEndpointUrl

指定 URL 基础地址,它插入到自动生成的 WADL 接口的 wadl:resources/@base 属性中。

serviceAnnotation

(仅限Spring) 在 Spring 中指定自动发现的服务注解类名称。当与 basePackages 属性结合使用时,此选项限制了自动发现类的集合,使其仅包含由 此注解类型标注的类。guess!这是否正确?

serviceClass

指定 JAX-RS root 资源类的名称(实施 JAX-RS 服务)。在这种情况下,该类由 Apache CXF 实例化,而不是按 Blueprint 或 Spring 进行实例化。如果要实例化 Blueprint 或 Spring 中的类,请使用 jaxrs:serviceBeans 子元素。

serviceName

在特殊情况下,为 JAX-RS 端点指定 service QName (使用格式 ns:name)。详情请查看 “使用 JMS 传输”一节

staticSubresourceResolution

如果为 true,则禁用静态子资源的动态解析。默认为 false

transportId

用于选择非标准传输层(代替 HTTP)。特别是,您可以通过将此属性设置为 http://cxf.apache.org/transports/jms 来选择 JMS 传输。详情请查看 “使用 JMS 传输”一节

abstract

(仅限Spring) 指定是否 bean 是抽象 Bean。抽象 Bean 充当 concrete bean 定义的父项,且不会实例化。默认值为 false。把它设置为 true 会指示 bean 工厂不会实例化 bean。

dependent-on

(仅限Spring) 指定端点在可实例化端点前实例化的 Bean 列表。

18.1.3. jaxrs:server Child Elements

子元素

表 18.2 “JAX-RS 服务器端点 Child Elements” 描述 jaxrs:server 元素的子元素。

表 18.2. JAX-RS 服务器端点 Child Elements
元素描述

jaxrs:executor

指定用于该服务的 Java Executor (线程池实现)。这使用嵌入式 bean 定义来指定。

jaxrs:features

指定配置 Apache CXF 高级功能的 Bean 列表。您可以提供 bean 引用列表或嵌入式 Bean 列表。

jaxrs:binding

未使用。

jaxrs:dataBinding

指定实施端点使用的数据绑定的类。这使用嵌入式 bean 定义来指定。如需了解更多详细信息,请参阅 “指定数据绑定”一节

jaxrs:inInterceptors

指定处理入站请求的拦截器列表。如需更多信息,请参阅 第 VII 部分 “开发 Apache CXF Interceptors”

jaxrs:inFaultInterceptors

指定处理入站故障消息的拦截器列表。如需更多信息,请参阅 第 VII 部分 “开发 Apache CXF Interceptors”

jaxrs:outInterceptors

指定处理出站回复的拦截器列表。如需更多信息,请参阅 第 VII 部分 “开发 Apache CXF Interceptors”

jaxrs:outFaultInterceptors

指定处理出站故障消息的拦截器列表。如需更多信息,请参阅 第 VII 部分 “开发 Apache CXF Interceptors”

jaxrs:invoker

指定服务使用的 org.apache.cxf.service.Invoker 接口的实现。 [a]

jaxrs:serviceFactories

为您提供对与此端点关联的 JAX-RS 根资源生命周期的最大控制程度。此元素的子项(必须是 org.apache.cxf.jaxrs.lifecycle.ResourceProvider 类型)的实例来创建 JAX-RS 根资源实例。

jaxrs:properties

指定与端点一起传递的属性的 Spring 映射。这些属性可用于控制诸如启用 MTOM 支持等功能。

jaxrs:serviceBeans

此元素的子项是(bean 元素)的实例,或引用(ref 元素) JAX-RS root 资源。请注意,在这种情况下,如果 bean 元素中存在 scope 属性 (Spring only),则忽略。

jaxrs:modelBeans

包含对一个或多个 org.apache.cxf.jaxrs.model.UserResource beans 的引用列表,它们是资源模型的基本元素(与 jaxrs:resource 元素相对应)。详情请查看 第 18.3 节 “使用 Model Schema 定义 REST 服务”

jaxrs:model

直接在此端点中定义资源模型(即,此 jaxrs:model 元素可以包含一个或多个 jaxrs:resource 元素)。详情请查看 第 18.3 节 “使用 Model Schema 定义 REST 服务”

jaxrs:providers

允许您将一个或多个自定义 JAX-RS 提供程序注册到此端点。此元素的子项是(bean 元素)或对(ref 元素) JAX-RS 提供程序的引用。

jaxrs:extensionMappings

当 REST 调用的 URL 以文件扩展名结尾时,您可以使用此元素将它自动与特定的内容类型关联。例如,.xml 文件扩展可以与 application/xml 内容类型关联。详情请查看 “扩展映射和语言映射”一节

jaxrs:languageMappings

当 REST 调用的 URL 以语言后缀结尾时,您可以使用此元素映射到特定语言。例如,.en 语言后缀可以与 en-GB 语言关联。详情请查看 “扩展映射和语言映射”一节

jaxrs:schemaLocations

指定用于验证 XML 消息内容的一个或多个 XML 模式。此元素可以包含一个或多个 jaxrs:schemaLocation 元素,每个元素指定 XML 模式文件的位置(通常是 类路径 URL)。详情请查看 “模式验证”一节

jaxrs:resourceComparator

允许您注册自定义资源比较器,它实现了与特定资源类或方法匹配的传入 URL 路径的算法。

jaxrs:resourceClasses

如果要从类名称 创建多个资源,则只能使用 jaxrs:server/@serviceClass 属性而不是 jaxrs:server/@serviceClass 属性。jaxrs:resourceClasses 的子项必须是 class 元素,并将 name 属性设置为资源类的名称。在这种情况下,类由 Apache CXF 实例化,而不是由 Blueprint 或 Spring 进行实例化。

[a] Invoker 实现控制如何调用服务。例如,它控制每个请求是否由服务实施的新实例处理,还是在调用之间保留状态。
Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.