41.2.3. 实施提供程序对象
概述
提供程序接口相对容易实现。它只有一个方法 调用()
,必须实现。另外,它有三个简单要求:
-
实施必须具有
@WebServiceProvider
注释。 - 实施必须有一个默认的公共构造器。
实施必须实现输入的 Provider 接口版本。
换句话说,您无法实现 Provider<T> 接口。您必须实现使用统一数据类型的接口版本,该版本包括在 第 41.2.2 节 “数据类型” 中列出的。例如,您可以实现一个 Provider<SAXSource> 实例。
实施提供程序接口的复杂性是在处理请求消息和构建正确响应的逻辑中。
使用消息
与基于 SEI 的更高级别的服务实现不同,提供商实现将请求接收为原始 XML 数据,并且必须发送响应作为原始 XML 数据。这要求开发人员对所实施服务所使用的消息的了解。这些详细信息通常可在描述该服务的 WSDL 文档中找到。
WS-I 基本 配置集提供有关服务使用的信息,包括:
请求的 root 元素基于与调用操作的
wsdl:operation
元素的name
属性的值。警告如果服务使用 doc/literal 裸机消息,则请求的根元素将基于
wsdl:operation
元素引用的wsdl:part
元素的值。- 所有消息的根元素是命名空间合格的。
如果服务使用 rpc/literal 消息,则消息中的顶级元素不会具有命名空间限定性。
重要顶级元素的子项可能具有命名空间授权,但必须检查其架构定义。
- 如果服务使用 rpc/literal 消息,则顶级元素都不能为空。
- 如果服务使用 doc/literal 消息,则消息的 schema 定义会确定任何元素是否合格。
@WebServiceProvider 注释
为了被 JAX-WS 认可为服务实施,提供程序实施必须与 @WebServiceProvider
注释进行解码。
表 41.2 “@WebServiceProvider
Properties” 描述可以为 @WebServiceProvider
注释设置的属性。
表 41.2. @WebServiceProvider
Properties
属性 | 描述 |
---|---|
|
指定定义该服务端点的 |
|
指定包含该服务端点的 |
| 指定服务的 WSDL 定义的目标名称空间。 |
| 指定定义 服务的 WSDL 文件的 URI。 |
所有这些属性都是可选的,默认情况下为空。如果您将其留空,Apache CXF 将使用实施类中的信息创建值。
实施 invoke()方法
Provider 接口只有一个方法,即 调用()
,必须实现。invoke()
方法接收发送到所实施提供程序接口类型声明的传入请求,并返回将响应消息打包为同一类型对象。例如,一个 Provider<SOAPMessage> 接口的实现会将请求接收为 SOAPMessage
对象,并返回响应作为 SOAPMessage
对象。
Provider 实施使用的消息传递模式决定了请求和响应消息包含的绑定特定信息的数量。使用消息模式实现的实现会接收所有绑定特定打包程序和标头以及请求。它们还必须将所有绑定特定打包程序和标头添加到响应消息中。使用有效负载模式实现的实施仅接收请求的正文。使用有效负载模式实现的 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> 实现” 中的代码执行以下操作:
指定类实现实现服务的 Provider 对象,其 wsdl:service
元素命名为 stockQuoteReporter
,其 wsdl:port
元素名为 stockQuoteReporterPort
。
指定此提供程序的实现使用有效负载模式。
提供所需的默认公共构造器。
提供 调用()
方法的实施,它采用 DOMSource
对象并返回 DOMSource
对象。