41.2. 在服务提供商中使用 XML


摘要

Provider 接口是一个低级 JAX-WS API,它允许您实施一个服务供应商,作为原始 XML 直接处理消息。消息不会打包成 JAXB 对象,然后传递到实现 Provider 接口的对象。

41.2.1. 消息传递模式

概述

实施 Provider 接口的对象有两种 消息传递模式

您指定的消息传递模式决定了传递到您的实施的消息传递详情级别。

消息模式

在使用 消息模式 时,提供程序实施可用于完成消息。完整消息中包含任何绑定特定标头和打包程序。例如,使用 SOAP 绑定的供应商实现会接收请求作为完全指定的 SOAP 消息。所有从实施返回的响应都必须是完全指定的 SOAP 消息。

要指定 Provider 实现使用消息模式,方法是提供值 java.xml.ws.Service.Mode.MESSAGE 作为 javax.xml.ws.ServiceMode 注解的值,如 例 41.9 “指定供应商实施使用消息模式” 所示。

例 41.9. 指定供应商实施使用消息模式

@WebServiceProvider
@ServiceMode(value=Service.Mode.MESSAGE)
public class stockQuoteProvider implements Provider<SOAPMessage>
{
  ...
}

有效负载模式

有效负载模式中,提供程序实施仅用于消息有效负载。例如,在有效负载模式下工作的供应商实施只适用于 SOAP 消息的正文。绑定层处理任何绑定级别的打包程序和标头。

在使用不使用特殊打包程序的绑定时,如 Apache CXF XML 绑定、有效负载模式和消息模式提供相同的结果。

要指定 Provider 实现使用有效负载模式,方法是提供值 java.xml.ws.Service.Mode.PAYLOAD 作为 javax.xml.ws.ServiceMode 注解的值,如 例 41.10 “指定 Provider Implementation Uses Payload Mode” 所示。

例 41.10. 指定 Provider Implementation Uses Payload Mode

@WebServiceProvider
@ServiceMode(value=Service.Mode.PAYLOAD)
public class stockQuoteProvider implements Provider<DOMSource>
{
  ...
}

如果没有为 @ServiceMode 注释提供值,则 Provider 实现使用 payload 模式。

41.2.2. 数据类型

概述

由于它们是低级对象,因此提供商实施无法使用与更高级别的消费者 API 相同的 JAXB 生成的类型。供应商实现用于以下类型的对象:

使用 Source 对象

提供程序实施可以接受并返回来自 javax.xml.transform.Source 接口的对象。源对象是包含 XML 文档的低级别对象。每个 Source 实施都提供了访问存储 XML 文档和操作其内容的方法。以下对象实现 Source 接口:

DOMSource
将 XML 消息作为文档对象模型(DOM)树保存.XML 消息作为一组节点对象存储,它们通过 get Node () 方法进行访问。可以使用 setNode () 方法更新或添加到 DOM 树中。
SAXSource
将 XML 消息保存为 XML (SAX)对象的简单 API。SAX 对象包含一个 InputSource 对象,该对象保存原始数据和解析原始数据的 XMLReader 对象。
StreamSource
将 XML 消息作为数据流保存。数据流可以与任何其他数据流相同。

如果创建 Provider 对象使其使用通用源对象,Apache CXF 会将消息返回为 SAXSource 对象。

可以使用端点 的源-preferred-format 属性更改此行为。有关配置 Apache CXF 运行时的信息,请参阅 第 IV 部分 “配置 Web 服务端点”

重要

在使用 Source 对象时,开发人员将负责确保所有所需的特定绑定程序都添加到消息中。例如,当与希望 SOAP 消息的服务交互时,开发人员必须确保将所需的 SOAP envelope 添加到传出请求中,并且 SOAP envelope 的内容正确。

使用 SOAPMessage 对象

当以下条件满足时,提供程序实施可以使用 javax.xml.soap.SOAPMessage 对象:

  • Provider 实现使用 SOAP 绑定
  • Provider 实现使用消息模式

SOAPMessage 对象保存 SOAP 消息。它们包含一个 SOAPPart 对象和零个或更多 AttachmentPart 对象。SOAPPart 对象包含 SOAP 消息的特定部分,包括 SOAP envelope、任何 SOAP 标头和 SOAP 消息正文。AttachmentPart 对象包含作为附件传递的二进制数据。

使用 DataSource 对象

当以下条件满足时,提供程序实施可以使用实现 javax.activation.DataSource 接口的对象:

  • 实现使用 HTTP 绑定
  • 实现使用消息模式

Datasource 对象提供了一种机制,可用于处理来自各种来源的 MIME 类型数据,包括 URL、文件和字节阵列。

41.2.3. 实施供应商对象

概述

提供者界面相对容易实施。它只具有一种方法,调用() 必须被实施。另外,它有三个简单的要求:

  • 实施必须含有 @WebServiceProvider 注释。
  • 实施必须具有默认的公共构造器。
  • 实施必须实施键入的提供者接口版本。

    换句话说,您无法实施 Provider<T> 接口。您必须实现使用 concrete 数据类型的接口版本,如 第 41.2.2 节 “数据类型” 中列出的。例如,您可以实施 Provider<SAXSource> 的实例。

实施 Provider 接口的复杂性是在处理请求消息并构建正确的响应的逻辑中。

使用消息

与基于较高级别的 SEI 服务实施不同,提供商实施将请求作为原始 XML 数据接收,并且必须作为原始 XML 数据发送响应。这要求开发人员对正在实施的服务所使用的消息有一定了解。这些详细信息通常可在描述服务的 WSDL 文档中找到。

WS-I 基本 配置集提供有关服务使用的信息的指南,包括:

  • 请求的 root 元素基于 wsdl:operation 元素的 name 属性的值,与调用的操作对应。

    警告

    如果服务使用 doc/literal bare 消息,则请求的 root 元素基于 wsdl:part 元素的 name 属性的值。

  • 所有消息的根元素都是命名空间限定。
  • 如果服务使用 rpc/literal 消息,则消息中的顶层元素不会被命名空间限定。

    重要

    顶级元素的子项可能是命名空间合格的,但在某些情况下您必须检查其架构定义。

  • 如果服务使用 rpc/literal 消息,则顶级元素都为空。
  • 如果服务使用 doc/literal 消息,则消息的 schema 定义决定任何元素是否满足命名空间。

@WebServiceProvider 注释

要将 JAX-WS 识别为服务实施,提供程序实施必须被 @WebServiceProvider 注释进行解码。

表 41.2 “@WebServiceProvider Properties” 描述可以为 @WebServiceProvider 注释设置的属性。

表 41.2. @WebServiceProvider Properties
属性描述

portName

指定定义服务端点的 wsdl:port 元素的 name 属性的值。

serviceName

指定包含服务端点的 wsdl:service 元素的 name 属性的值。

targetNamespace

指定服务 WSDL 定义的 targetname 空间。

wsdlLocation

指定定义该服务的 WSDL 文档的 URI。

所有这些属性都是可选的,默认情况下为空。如果您为空,Apache CXF 将使用实施类中的信息创建值。

实施 call ()方法

Provider 接口只有一个方法 calls (),必须实施它。调用() 方法接收打包为实施的 Provider 接口类型的对象类型的传入请求,并将响应消息返回成同一类型的对象。例如,实施 Provider<SOAPMessage> 接口接收请求作为 SOAPMessage 对象,并将响应作为 SOAPMessage 对象返回。

提供程序实施所用的消息传递模式决定了请求和响应消息中包含的特定信息的绑定量。使用消息模式的实现会接收所有绑定器和标头,以及请求。它们还必须将所有绑定程序和标头添加到响应消息。使用有效负载模式的实现仅接收请求的正文。使用有效负载模式返回的 XML 文档被放入请求消息的正文中。

例子

例 41.11 “provider<SOAPMessage> 实现” 显示一个供应商实施,用于消息模式的 SOAPMessage 对象。

例 41.11. provider<SOAPMessage> 实现

import javax.xml.ws.Provider;
import javax.xml.ws.Service;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceProvider;

@WebServiceProvider(portName="stockQuoteReporterPort"
                    serviceName="stockQuoteReporter")
@ServiceMode(value="Service.Mode.MESSAGE")
public class  stockQuoteReporterProvider implements Provider<SOAPMessage>
{
public stockQuoteReporterProvider()
  {
  }

public SOAPMessage invoke(SOAPMessage request)
  {
  SOAPBody requestBody = request.getSOAPBody();
  if(requestBody.getElementName.getLocalName.equals("getStockPrice"))
    {
    MessageFactory mf = MessageFactory.newInstance();
      SOAPFactory sf = SOAPFactory.newInstance();

    SOAPMessage response = mf.createMessage();
      SOAPBody respBody = response.getSOAPBody();
      Name bodyName = sf.createName("getStockPriceResponse");
      respBody.addBodyElement(bodyName);
      SOAPElement respContent = respBody.addChildElement("price");
      respContent.setValue("123.00");
      response.saveChanges();
    return response;
    }
    ...
  }
}

例 41.11 “provider<SOAPMessage> 实现” 中的代码执行以下操作:

指定以下类实施实施实施服务(其 wsdl:service 元素名为 stockQuoteReporter )的 Provider 对象,其 wsdl:port 元素名为 stockQuoteReporterPort

指定此提供程序实施使用消息模式。

提供所需的默认公共构造器。

提供 调用()方法的 实现,它采用 SOAPMessage 对象并返回 SOAPMessage 对象。

从传入 SOAP 消息的正文中提取请求消息。

检查请求消息的根元素,以确定如何处理请求。

创建构建响应所需的工厂。

为响应构建 SOAP 消息。

将响应返回为 SOAPMessage 对象。

例 41.12 “provider<DOMSource> 实施” 显示在有效负载模式中使用 DOMSource 对象进行提供程序实施的示例。

例 41.12. provider<DOMSource> 实施

import javax.xml.ws.Provider;
import javax.xml.ws.Service;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceProvider;

@WebServiceProvider(portName="stockQuoteReporterPort" serviceName="stockQuoteReporter")
@ServiceMode(value="Service.Mode.PAYLOAD")
public class  stockQuoteReporterProvider implements Provider<DOMSource>
public stockQuoteReporterProvider()
  {
  }

public DOMSource invoke(DOMSource request)
  {
    DOMSource response = new DOMSource();
    ...
    return response;
  }
}

例 41.12 “provider<DOMSource> 实施” 中的代码执行以下操作:

指定该类实施了实施服务(其 wsdl:service 元素名为 stockQuoteReporter )的 Provider 对象,其 wsdl:port 元素名为 stockQuoteReporterPort

指定此提供程序实施使用有效负载模式。

提供所需的默认公共构造器。

提供 调用() 方法的实施,该方法采用 DOMSource 对象并返回 DOMSource 对象。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

© 2024 Red Hat, Inc.