29.4. 使用合同解析器


概述

在运行时解析 WSDL 文档位置的最涉及的机制是实施您自己的自定义合同解析器。这要求您提供 Apache CXF 特定 ServiceContractResolver 接口的实现。您还需要将自定义解析器注册到总线。

正确注册后,将使用自定义合同解析器来解决任何所需的 WSDL 和架构文档的位置。

实施合同解析器

合同解析器是 org.apache.cxf.endpoint.ServiceContractResolver 接口的实现。如 例 29.3 “ServiceContractResolver Interface” 所示,这个接口有一个方法 getContractLocation (),需要实现它。getContractLocation () 采用服务的 QName,并返回服务的 WSDL 合同的 URI。

例 29.3. ServiceContractResolver Interface

public interface ServiceContractResolver
{
   URI getContractLocation(QName qname);
}

用于解析 WSDL 合同位置的逻辑特定于应用。您可以添加可解析来自 UDDI registry、数据库、文件系统上的自定义位置或您选择的任何其他机制的逻辑。

以编程方式注册合同解析器

在 Apache CXF 运行时将使用您的合同解析器前,您必须将其注册到合同解析器 registry。合同解析器 registry 实施 org.apache.cxf.endpoint.ServiceContractResolverRegistry 接口。但是,您不需要实施自己的 registry。Apache CXF 在 org.apache.cxf.endpoint.ServiceContractResolverRegistryImpl 类中提供默认实现。

要将合同解析器注册到默认 registry,请执行以下操作:

  1. 获取对默认总线对象的引用。
  2. 使用总线的 getExtension () 方法从总线获取服务合同 registry。
  3. 创建合同解析器的实例。
  4. 使用 registry 的 register () 方法将合同解析器注册到 registry。

例 29.4 “注册合同解析器” 显示将合同解析器注册到默认 registry 的代码。

例 29.4. 注册合同解析器

BusFactory bf=BusFactory.newInstance();
Bus bus=bf.createBus();

ServiceContractResolverRegistry registry = bus.getExtension(ServiceContractResolverRegistry);

JarServiceContractResolver resolver = new JarServiceContractResolver();

registry.register(resolver);

例 29.4 “注册合同解析器” 中的代码执行以下操作:

获取总线实例。

获取总线的合同解析器 registry。

创建合同解析器实例。

将合同解析器注册到 registry。

使用配置注册合同解析器

您还可以实施合同解析器,以便通过配置将其添加到客户端。合同解析器采用这样一种方式,即当运行时读取配置并实例化解析器(解析器)时,解析器会自行注册。由于运行时处理初始化,因此您可以在运行时决定客户端是否需要使用合同解析器。

要实现合同解析器,以便可以通过配置将其添加到客户端中:

  1. 在您的合同解析器实施中添加 init () 方法。
  2. 在您的 init () 方法中添加逻辑,以将合同解析器注册到合同解析器 registry,如 例 29.4 “注册合同解析器” 所示。
  3. 使用 @PostConstruct 注释拒绝 init () 方法。

例 29.5 “可使用配置注册的服务合同解析器” 显示了可以使用 配置添加到客户端中的合同解析器实施。

例 29.5. 可使用配置注册的服务合同解析器

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.xml.namespace.QName;

import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;

public class UddiResolver implements ServiceContractResolver
{
  private Bus bus;
  ...

  @PostConstruct
  public void init()
  {
    BusFactory bf=BusFactory.newInstance();
    Bus bus=bf.createBus();
    if (null != bus)
    {
      ServiceContractResolverRegistry resolverRegistry = bus.getExtension(ServiceContractResolverRegistry.class);
      if (resolverRegistry != null)
      {
        resolverRegistry.register(this);
      }
    }
  }

  public URI getContractLocation(QName serviceName)
  {
    ...
  }
}

要将合同解析器注册到客户端,您需要向客户端的配置中添加 bean 元素。bean 元素的 class 属性是实施合同解析器的类的名称。

例 29.6 “Bean 配置合同解析器” 显示一个 bean,用于添加由 org.apache.cxf.demos.myContractResolver 类实现的配置解析器。

例 29.6. Bean 配置合同解析器

<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  ...
  <bean id="myResolver" class="org.apache.cxf.demos.myContractResolver" />
  ...
</beans>

合同解析顺序

创建新代理时,运行时使用合同注册表解析器来查找远程服务的 WSDL 合同。合同解析器 registry 按照注册解析器的顺序调用每个合同解析器的 getContractLocation () 方法。它返回从其中一个注册的合同解析器返回的第一个 URI。

如果您注册了一个在已知已知共享文件系统上解析 WSDL 合同的合同解析器,则它是唯一使用的合同解析器。但是,如果您随后注册了一个使用 UDDI 注册表解析 WSDL 位置的合同解析器,registry 就可以使用两个解析器来定位服务的 WSDL 合同。该注册表首先会尝试使用共享文件系统合同解析器查找合同。如果该合同解析器失败,registry 将尝试使用 UDDI 合同解析器查找它。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

© 2024 Red Hat, Inc.