25.2. 创建服务对象

概述

javax.xml.ws.Service 类代表 wsdl:service 元素,其中包含公开服务的所有端点的定义。因此,它提供可让您获得由 wsdl:port 元素定义的端点的方法,这些元素是用于在服务上执行远程调用的代理。

注意

Service 类提供抽象概念,允许客户端代码使用 Java 类型而不是使用 XML 文档。

create()方法

Service 类有两个静态 create() 方法,可用于创建新的 Service 对象。如 例 25.1 “service create() 方法” 所示,create() 方法采用 wsdl:service 元素的 QName 来代表 Service 对象,另一个则使用指定 WSDL 合同位置的 URI。

注意

所有服务发布他们的 WSDL 合同。对于 SOAP/HTTP 服务,URI 通常是附加了 ?wsdl 的服务的 URI。

例 25.1. service create() 方法

公共静态服务创建URLwsdlLocationQNameserviceNameWebServiceExceptionpublic 静态服务创建QNameserviceNameWebServiceException

serviceName 参数的值是一个 QName。其 namespace 部分的值是该服务的目标命名空间。该服务的目标命名空间在 @WebService 注释的 targetNamespace 属性中指定。QName 的本地部分的值是 wsdl:service 元素的 name 属性的值。您可以使用以下方法之一确定这个值: .它在 @WebService 注释的 serviceName 属性中指定。

  1. Service 附加到 @WebService 注释的 name 属性的值。
  2. Service 附加到 SEI 的名称。
重要

在 OSGi 环境中部署的 CXF 消费者需要特殊处理,以避免发生类 NotFoundException的可能性。对于包含编程创建的 CXF 消费者的每个捆绑包,您需要创建一个单例 CXF 默认总线,并确保所有捆绑包的 CXF 使用者都使用它。如果没有这种保护机制,可以为一个捆绑包分配在另一个捆绑包中创建的 CXF 默认总线,这可能会导致继承捆绑包失败。

例如,假设捆绑包 A 没有明确设置 CXF 默认总线,并且被分配了捆绑包 B 中创建的 CXF 默认总线。如果捆绑包 A 中的 CXF 总线需要配置额外功能(如 SSL 或 WS-Security),或者需要从捆绑包 A 中加载特定类或资源,则会失败。这是因为 CXF 总线实例将线程上下文类加载程序设置为创建它的捆绑包的类加载程序(本例中为 B)。此外,某些框架,比如 ws4j(在 CXF 中实施 WS-Security)使用 TCCL 从捆绑包内部加载资源,如 calback 处理程序类或其他属性文件。因为分配了捆绑包 B 的默认 CXF 总线及其 TCCL,因此 ws4j 层无法从捆绑包 A 加载所需资源,从而导致 ClassNotFoundException 错误。

要创建单例 CXF 默认总线,请将此代码插入到创建服务对象 的主 方法的开头,如 “示例”一节 所示:

BusFactory.setThreadDefaultBus(BusFactory.newInstance().createBus());

示例

例 25.2 “创建服务 对象” 显示为 例 24.7 “完全注解的 SEI” 中显示的 SEI 创建 Service 对象的代码。

例 25.2. 创建服务 对象

package com.fusesource.demo;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class Client
{
public static void main(String args[])
  {
    BusFactory.setThreadDefaultBus(BusFactory.newInstance().createBus());
    QName serviceName = new QName("http://demo.redhat.com", "stockQuoteReporter");
    Service s = Service.create(serviceName);
   ...
  }
}

例 25.2 “创建服务 对象” 中的代码执行以下操作:

创建一个单例 CXF 默认总线,供服务的所有 CXF 使用者使用。

使用 targetNamespace 属性和 @WebService 注解的 name 属性,为服务构建 QName。

调用单一参数 create() 方法以创建新的 Service 对象。

注意

使用单一参数 create() 可让您获得访问 WSDL 合同的任何依赖项。