实现静态 JAX-WS Web Service 客户机
可以根据 Web Services for Java™ Platform, Enterprise Edition (Java EE) 规范和 Java API for XML-Based Web Services (JAX-WS) 编程模型开发静态 Web Service 客户机。
开始之前

关于此任务
- 基于 JAX-WS 编程模型开发 Web Service 客户机
可同时访问和调用 JAX-WS Web Service 的 Web Service 客户机根据 Web Services for Java Platform, Enterprise Edition (Java EE) 规范进行开发。应用程序服务器支持 Enterprise JavaBeans (EJB) 客户机、Java EE 应用程序客户机、JavaServer Pages (JSP) 文件和基于 JAX-WS 编程模型的 servlet。如果 Web Service 描述语言 (WSDL) 文件符合 Web Services-Interoperability (WS-I) 基本概要文件,那么基于 JAX-RPC 规范的 Web Service 客户机可以调用基于 JAX-WS 的 Web Service。
JAX-WS 客户机编程模型支持 Dispatch client API 和 Dynamic proxy client API。Dispatch client API 是动态客户机编程模型,而 JAX-WS 的静态客户机编程模型是 Dynamic proxy client。Dispatch 和 Dynamic proxy client 支持对 JAX-WS Web Service 进行同步和异步调用。
Dynamic proxy client 基于提供的服务端点接口 (SEI) 调用 Web Service。JAX-WS 动态代理实例利用基本 Java SE 运行时环境 (JRE) 6 中的动态代理功能。如果要开发静态客户机,那么必须使用 WSDL 文件开始开发。
相对而言,Dispatch client API javax.xml.ws.Dispatch 是面向 XML 消息传递的客户机,适用于首选 XML 构造的高级 XML 开发者。Dispatch API 可以在 PAYLOAD 或 MESSAGE 方式下发送数据。使用 PAYLOAD 方式时,Dispatch client 仅负责提供 soap:Body 的内容,而 JAX-WS 将有效内容包括在 soap:Envelope 元素中。使用 MESSAGE 方式时,Dispatch client 负责提供整个 SOAP 包络。如果要开发动态客户机,那么不需要 WSDL 文件。
要根据 JAX-WS 编程模型开发 Web Service 客户机,必须确定最适合 Web Service 应用程序需要的客户机模型。如果要让 Web Service 客户机基于服务端点接口使用动态代理来调用服务,请使用 Dynamic proxy API 来开发静态 Web Service 客户机。创建代理后,客户机应用程序可以调用这些代理上的方法,如同调用服务端点接口的标准实现。但是,如果要直接处理 XML(而不是 Java 抽象)和处理消息结构或消息有效内容结构,请使用 Dispatch API 来开发动态 Web Service 客户机。请阅读关于实现动态 JAX-WS Web Service 客户机的信息以了解如何开发动态 Web Service 客户机。
完成此任务,从 WSDL 文件着手开发静态 Web Service 客户机。
要使用静态或动态 JAX-WS 客户机异步调用 Web Service,请确定是要实现回调还是轮询模型。请阅读关于通过异步方式调用 JAX-WS Web Service 的内容,以了解有关对 Web Service 客户机实现异步回调或轮询的更多信息。服务和客户机的 JAX-WS 编程模型使用注释来表示以独立于供应商的方式在 JAX-RPC 客户机绑定中提供的信息。
- 受管和非受管 JAX-WS Web Service 客户机
在使用 JAX-WS 编程模型时,应用程序服务器支持受管和非受管 Web Service 客户机:
- 受管客户机
Web Service for Java EE 客户机由 Java 规范要求 (JSR) 109 定义并且由于在 Java EE 容器中运行,所以是受管客户机。这些客户机打包为企业归档 (EAR) 文件并且包含充当服务请求者的组件。这些组件由 Java EE 客户机应用程序、Web 组件(例如 servlet 或 JavaServer Pages (JSP))或会话 Enterprise JavaBeans (EJB) 组成。Web Service 受管客户机使用 JSR 109 API 和部署信息来查找和调用 Web Service。
对于受管客户机,可以使用 Java 命名和目录接口 (JNDI) 查询来执行服务查询,也可以使用注释来注入 JAX-WS 服务或端口的实例。请阅读“设置用户名令牌 Web Service 安全性、数字签名 Web Service 安全性以及轻量级第三方认证 (LTPA) 令牌 Web Service 安全性”。以下代码是符合 JSR 109 的上下文查询的示例:
InitialContext ctx = new InitialContext(); FredsBankService service =(FredsBankService)ctx.lookup("java:comp/env/service/FredsBankService"); FredsBank fredsBank = service.getFredsBankPort(); long balance = fredsBank.getBalance();
可以使用 @WebServiceRef 或 @Resource 注释来声明受管客户机。使用这些注释将导致注释指定的类型将绑定到 JNDI 名称空间中。在字段或方法上使用注释时,它们也会导致注入 JAX-WS 服务或端口实例。可以在客户机部署描述符中使用这些注释,而不是声明 service-ref 条目。您仍可以使用客户机部署描述符来声明 JAX-WS 受管客户机,这与 JAX-RPC 受管客户机相似。也可以使用部署描述符来覆盖并增加 @WebServiceRef 和 @Resource 注释指定的信息。使用 @WebServiceRef 注释绑定并注入 JAX-WS 服务或端口实例。只能使用 @Resource 注释来绑定并注入 JAX-WS 服务实例。 使用这两个注释中的任意一个来声明 JAX-WS 受管客户机都只在特定的类类型中受支持。这些类类型包括 JAX-WS 端点实现类、JAX-WS 处理程序类、企业 Bean 类和 servlet 类。
以下示例使用 @WebServiceRef 注释来获取 FredsBank 的实例:
现在在类中,不必初始化 fredsBank 字段。您可以直接使用此字段:@WebServiceRef(name=”service/FredsBankPort”, value=FredsBankService.class) FredsBank fredsBank;
long balance = fredsBank.getBalance();
您也可以使用 @WebServiceRef 注释来获取 JAX-WS 服务类的实例;例如:@WebServiceRef(name=”service/FredsBankService”) FredsBankService service;
现在在类中,不必初始化 service 字段。您可以直接使用此字段:FredsBank fredsBank = service.getFredsBankPort(); long balance = fredsBank.getBalance();
除了 @WebServiceRef 注释,您还可以使用 @Resource 注释来获取 JAX-WS 服务类的实例;例如:@Resource(name=”service/FredsBankService”, type=FredsBankService.class) FredsBankService service;
就像使用 @WebServiceRef 注释一样,您现在可以在不进行实例化的情况下使用 service 字段;例如:FredsBank fredsBank = service.getFredsBankPort(); long balance = fredsBank.getBalance();
可以在类上使用 @Resource 或 @WebServiceRef 注释。在这种情况下,必须使用 JNDI 来查找 JAX-WS 服务或端口;例如:@WebServiceRef(name=”service/FredsBankService”, type=FredsBankService”) public class J2EEClientExample { … … public static void main(String[] args) { … … InitialContext ctx = new InitialContext(); FredsBankService service =(FredsBankService)ctx.lookup("java:comp/env/service/FredsBankService"); FredsBank fredsBank = service.getFredsBankPort(); long balance = fredsBank.getBalance(); } … }
有关使用 @WebServiceRef 和 @Resource 注释的更多信息,请参阅 JSR-109、JSR-224、JSR-250 和Java Platform Enterprise Edition 5 (Java EE 5) 的规范。
如前上述,使用注释或 JNDI 来获取 JAX-WS 服务和端口的实例时,请不要对返回的对象进行实例化。这样做会导致非受管客户机实例。以下示例显示使用错误的示例:@WebServiceRef(name=”service/FredsBankService”) FredsBankService service; service = new FredsBankService(); // client becomes unmanaged.
对于由 @WebServiceRef 或 @Resource 注释声明的 JAX-WS 受管客户机,以及使用客户机部署描述符中的 service-ref 条目声明的客户机,可以使用管理控制台来提供该客户机使用的端点 URL。此指定的 URL 将覆盖客户机使用的 WSDL 文档中的端点 URL。要了解有关指定此端点 URL 的更多信息,请参阅“配置 Web Service 客户机绑定”文档。
- 非受管客户机
使用 JAX-WS 运行时环境来调用 Web Service 并且不在任何 Java EE 容器中运行的 Java Platform, Standard Edition (Java SE 6) 客户机称为非受管客户机。 Web Service 非受管客户机是独立的 Java 客户机,它可以直接检查 WSDL 文件并通过使用 JAX-WS API 制定对 Web Service 的调用。这些客户机将打包为不包含任何部署信息的 JAR 文件。
- 受管客户机
从 WebSphere Application Server V7.0 开始,将扫描 Java EE 5 应用程序模块(Web 应用程序模块 V2.5 或更高版本,或者 EJB 模块 V3.0 或更高版本)以获取用于标识 JAX-WS 服务和客户机的注释。然而,缺省情况下,考虑到性能方面的因素,不会扫描 Java EE 5 之前的应用程序模块(Web 应用程序模块 V2.4 或更早版本,或者 EJB 模块 V2.1 或更早版本)来获取 JAX-WS 注释。在 V6.1 Feature Pack for Web Services 中,缺省行为是在安装应用程序期间扫描 Java EE 5 之前的 Web 应用程序模块以识别 JAX-WS 服务,以及扫描 Java EE 5 之前的 Web 应用程序模块和 EJB 模块以查找服务客户机。因为 WebSphere Application Server V7.0 和更高版本的缺省行为是不在应用程序安装或服务器启动期间扫描 Java EE 5 之前的模块以获取注释,所以为了保持与先前发行版中功能部件包的向后兼容性,您必须在 Web 应用程序归档 (WAR) 文件或 EJB 模块的 META-INF/MANIFEST.MF 中配置 UseWSFEP61ScanPolicy 属性,或在服务器上定义 Java 虚拟机定制属性 com.ibm.websphere.webservices.UseWSFEP61ScanPolicy 以请求在应用程序安装和服务器启动期间进行扫描。要了解有关注释扫描的更多信息,请参阅 JAX-WS 注释信息。
过程
结果
您已创建并测试 Web Service 客户机应用程序。
下一步做什么
开发 Web Service 应用程序客户机并且静态地绑定客户机后,实现使用的服务端点是您在开发流程中使用的 WSDL 文件中识别的那个端点。安装 Web Service 应用程序期间或者在安装后,您可能要更改服务端点。对于受管客户机,可以使用管理控制台或者 wsadmin 脚本编制工具更改端点。对于非受管 JAX-WS Web Service 客户机,可以在客户机应用程序中更改端点。
您还可以考虑通过实现 Web Service 客户机的扩展来定制 Web Service。这些扩展的一些示例包括在 SOAP 头中发送和接收值或发送和接收 HTTP 或 Java 消息服务 (JMS) 传输头。 要了解有关这些扩展的更多信息,请阅读有关“实现 Web Service 客户机扩展”的相关信息。