使用 JAX-WS API 开发动态客户机

Java™ API for XML-Based Web Services (JAX-WS) 支持对服务端点操作进行动态调用。

关于此任务

JAX-WS 提供新的动态 Dispatch client API,此 API 更通用,并且比现有的基于 Java API for XML-based RPC (JAX-RPC) 的动态调用接口 (DII) 更灵活。Dispatch client 接口 javax.xml.ws.Dispatch 是面向 XML 消息传递的客户机,适用于更喜欢使用 XML 构造在 XML 级别工作的高级 XML 开发者。要编写 Dispatch client,必须具有 Dispatch client API 和受支持的对象类型方面的专门知识,并了解关联 Web Service 描述语言 (WSDL) 文件的消息表示。

Dispatch API 可以在 PAYLOADMESSAGE 方式下发送数据。使用 PAYLOAD 方式时,Dispatch client 仅负责提供 <soap:Body> 的内容,而 JAX-WS 在 <soap:Envelope> 元素中包含输入有效内容。使用 MESSAGE 方式时,Dispatch client 负责提供整个 SOAP 包络。

Dispatch client API 要求应用程序客户机将消息或有效内容构造为 XML 并要求详细了解消息或消息有效内容。Dispatch client 在使用 Source 对象、Java XML 绑定体系结构 (JAXB) 对象或数据源对象时,可以使用 HTTP 绑定。Dispatch client 支持下列对象类型:
  • javax.xml.transform.Source:使用 Source 对象启用客户机以直接使用 XML API。可以将 Source 对象与 SOAP 和 HTTP 绑定配合使用。
  • JAXB 对象:借助 JAXB 对象,客户机可以通过根据 XML 模式生成的 JAXB 对象,使用 JAX-WS 应用程序来创建和控制 XML。JAXB 对象只能与 SOAP 和 HTTP 绑定配合使用。
  • javax.xml.soap.SOAPMessage:借助 SOAPMessage 对象,客户机可以处理 SOAP 消息。只能将 SOAPMessage 对象与 SOAP V1.1 或 SOAP V1.2 绑定配合使用。
  • javax.activation.DataSource:借助 DataSource 对象,客户机可以处理多用途因特网邮件扩充协议 (MIME) 消息。DataSource 仅与 HTTP 绑定配合使用。
Dispatch API 使用在 Java SE 运行时环境 (JRE) 6 中引入的 generics 概念。对于 Dispatch 接口上的每个 invoke() 方法,使用 generics 来确定返回类型。

过程

  1. 确定是否需要动态客户机在 PAYLOADMESSAGE 方式下发送数据。
  2. 创建服务实例并至少对其添加一个端口。 此端口传递协议绑定和服务端点地址信息。
  3. 使用 Service.Mode.PAYLOAD 方法或 Service.Mode.MESSAGE 方法创建 Dispatch<T> 对象。
  4. 配置 javax.xml.ws.BindingProvider 接口上的请求上下文属性。 使用请求上下文来指定其他诸如启用 HTTP 认证或指定端点地址之类的属性。
  5. 可选: 如果不想让 JAX-WS 运行时抛出 SOAPFaultException,请将 Dispatch API 的 RequestContext 选项上的 jaxws.response.throwExceptionIfSOAPFault 属性设置为 Boolean.TRUE

    以下示例说明了如何指定 Dispatch API 的 RequestContext 选项上的此属性:

    Dispatch<OMElement> dispatch = service.createDispatch( 
    portName, OMElement.class, Mode.MESSAGE);  
    BindingProvider bp = (BindingProvider)dispatch; 
    bp.getRequestContext().put(   
    "jaxws.response.throwExceptionIfSOAPFault", Boolean.FALSE);  
  6. 编写动态客户机的客户机请求消息。
  7. 以同步方式或异步方式使用 Dispatch client 来调用服务端点。
  8. 处理来自服务的响应消息。

结果

您已使用 Dispatch API 开发了动态 JAX-WS 客户机。请参阅 JAX-WS 2.0 规范第 4 章第 3 节,以了解有关如何使用 Dispatch client 的更多信息。

WebSphere® Application Server V8.0 开始,使用服务方法 addPort 添加的那些 JAX-WS 动态端口可能需要更多内存。在前发行版中,可以在多个服务实例之间共享动态端口的单个实例。在 V8.x 中,现在已将动态端口的范围限定为添加这些端口的服务实例。如果 JAX-WS 客户机有多个服务实例引用了同名的动态端口,那么将不再共享这些实例。这可能会增加该客户机的内存需求。当服务实例不在范围内时,将释放动态端口所使用的内存。但是,如果遇到与增加的内存用量相关的问题,那么可以还原该行为,以便在服务实例之间再次共享动态端口。要这样做,请将系统属性 jaxws.share.dynamic.ports.enable 设置为值 true。 但是,请注意,这样做可能会导致其他问题,例如在共享的动态端口之间未正确地应用策略集连接。如果将此标记设置为 true 并遇到这些问题中的某些问题,那么应该移除该标记设置。

在前发行版中,如果 Dispatch 客户机应用程序未提供 SOAP 操作,那么不会在出站消息上发送正确的 SOAP 操作。而是将 SOAP 操作设置为匿名操作。 从 WebSphere Application Server V8 开始,如果 Dispatch 客户机应用程序未提供 SOAP 操作,那么 JAX-WS 运行时环境将解析外发消息。它会确定正在调用的操作并使用该信息来确定适用于 SOAP 操作的相应值。出站消息的操作解析基于 SOAP 主体和消息编码(例如 Doc/Lit/Bare 和 Doc/Lit/Wrapped)。由于这种解析开销很大,所以可以设置一个属性。要始终禁用解析,请在系统级别设置该属性。要按消息来禁用解析,请在 JAX-WS 请求消息上下文上设置该属性。该属性定义为常量 org.apache.axis2.jaxws.Constants.DISPATCH_CLIENT_OUTBOUND_RESOLUTION 且具有字符串值 jaxws.dispatch.outbound.operation.resolution.enable。 属性的缺省值是空值,该解释为字符串 True,这将启用出站操作解析。将该属性设置为 False 可禁用出站操作解析。如果禁用解析,那么会按照先前步骤中所示,将出站消息中的 SOAP 操作设置为匿名操作。如果客户机通过 JAX-WS javax.xml.ws.BindingProvider 属性 SOAPACTION_USE_PROPERTYSOAPACTION_URI_PROPERTY 提供了 SOAP 操作,那么将使用该 SOAP 操作。因此,无论该属性的设置为何,都不会解析出站消息。 通过客户机来显式设置 SOAP 操作是最佳实践,这尤其适用于服务提供程序的性能。此实践可阻止解析入站消息,以将入站消息路由到正确的端点操作。

示例

以下示例说明了创建 Dispatch client 并调用样本 EchoService 服务端点的步骤。
String endpointUrl = ...;
		
QName serviceName = new QName("http://com/ibm/was/wssample/echo/",
 "EchoService");
QName portName = new QName("http://com/ibm/was/wssample/echo/",
 "EchoServicePort");
		
/** Create a service and add at least one port to it. **/ 
Service service = Service.create(serviceName);
service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, endpointUrl);
		
/** Create a Dispatch instance from a service.**/ 
Dispatch<SOAPMessage> dispatch = service.createDispatch(portName, 
SOAPMessage.class, Service.Mode.MESSAGE);
	
/** Create SOAPMessage request. **/
// compose a request message
MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);

// Create a message.  This example works with the SOAPPART.
SOAPMessage request = mf.createMessage();
SOAPPart part = request.getSOAPPart();

// Obtain the SOAPEnvelope and header and body elements.
SOAPEnvelope env = part.getEnvelope();
SOAPHeader header = env.getHeader();
SOAPBody body = env.getBody();

// Construct the message payload.
SOAPElement operation = body.addChildElement("invoke", "ns1",
 "http://com/ibm/was/wssample/echo/");
SOAPElement value = operation.addChildElement("arg0");
value.addTextNode("ping");
request.saveChanges();

/** Invoke the service endpoint. **/
SOAPMessage response = dispatch.invoke(request);

/** Process the response. **/

指示主题类型的图标 任务主题



时间戳记图标 最近一次更新时间: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_jaxwsdynclient
文件名:twbs_jaxwsdynclient.html