利用J2EE1.4创建Web服务
JAX-RPC使Web服务的实现标准化
在将用于XML远程过程调用的Java API(JAX-RPC)作为J2EE 1.4的一部分发布之前,开发人员没有标准化的方法来实现和使用在不同供应商的产品中公用的用Java编写的Web服务。没有标准化,这意味着开发人员不能使用跨J2EE供应商平台的通用技巧集来构建Web服务。
借助JAX-RPC,开发人员可以在Java平台上采用一个公用的API来开发Web服务。无论是在服务器上应用Oracle Application Server 10g Containers for J2EE (OC4J),还是在设计时应用Oracle JDeveloper 10g的JAX-RPC扩展,Oracle都是最早实施包含JAX-RPC的J2EE 1.4的厂商之一。
下面我们来介绍使用JAX-RPC API的步骤,包括创建一个简单的Java接口、基于该接口实现一个Java类、部署到一个J2EE 1.4容器,最后构建一个JAX-RPC客户端。
构建JAX-RPC接口及其实现
当将一个SOAP(简单对象访问协议)消息发送到一个Web服务端点时,Web服务被调用。所谓端点,系指服务器将解析该SOAP消息并将它转变为一个对底层组件的Java调用的地点。JAX-RPC为那些想要构建该端点的开发人员提供了编程路线图。对于要构建该端点的JAX-RPC开发人员来说,首先必需进行的两步是任何一个Java开发人员都熟悉的--开发一个Java接口,用于定义客户端将调用的公共方法集;然后开发一个实现这种接口的Java类。
例如,使用著名的Oracle模式SCOTT和同样有名的EMP表作为业务数据,你可以构建许多返回有用信息的Web服务。让我们来构建一个服务,它有一个将员工号作为参数并返回员工薪水的方法:
1 import java.rmi.*;
2 public interface EmpInterface extends java.rmi.Remote
3 {
4 public String getEmpSalary(Integer empNo) throws java.rmi.RemoteException;
5 }
关于该接口(EmpInterface)要注意两点:第一,它提供类java.rmi.Remote;第二,每个方法都产生异常java.rmi.RemoteException类。
如果你以前曾经实现过servlet或Enterprise JavaBean,那么你就会知道这两个类都是J2EE开发人员用于远程组件的传统服务器端类。因为Web服务端点恰好也是一个远程对象,所以JAX- RPC设计人员决定利用这些相同的类。它们的使用为现有的J2EE开发人员提供了向JAX-RPC自然过渡方法,他们只需利用他们的知识以及已经过证明有效的编程模型即可。
接下来,让我们来实现这个接口,以便你的Web服务能够做一些你感兴趣的事情--例如,查询EMP表,以获取某个员工的薪水情况。 清单1 显示了专注于方法的实现和JAX-RPC的某些重要方面的类的一部分。
在这段代码中,除了业务方法getEmpSalary的简单JDBC细节之外,要注意的主要概念是ServiceLifeCycle接口的init和 destroy方法。这两个方法使开发人员能够以标准方式实现启动逻辑或关闭逻辑--例如,用destroy方法实现一个JDBC连接清除代码序列。
发布JAX-RPC Web服务
创建了Web服务接口之后,就可以发布JAX-RPC Web服务了。要发布Web服务(即对它进行打包和部署,以便外部客户端能够向其发送并从其接收SOAP消息),需要按以下步骤进行:
为了完成这些步骤,你可以使用新发布的Oracle JDeveloper 10g 的JAX-RPC设计时环境。一个类似于命令行的软件Web Services Assembler(汇编程序)是OC4J的一部分。(这些工具可以从OTN下载,参见"下一步"框。)使用Jdeveloper向导,这些步骤很简单:识别你想要发布的类、选择你想要作为Web服务展示的方法、定义SOAP消息的风格(RPC/编码型的,RPC/文字型的,文字型文档等)。
在以前的一些版本中,为了保证互操作性,Oracle提供的Web服务的实现严格遵循规范的Web服务标准SOAP, WSDL和UDDI,但是,像当时所有J2EE供应商的实现一样,Oracle的实现也是应用服务器特定的实现。因此,以前的这种老风格的刻板步骤对 JAX-RPC来说也非常类似。然而,现在JAX-RPC标准化了各个J2EE供应商的配置,因而不仅能提供Web服务级别上的互操作性,而且还能提供实现级别上的可移植性。
由此产生的文件结构除了需要实现和接口类文件之外,还需要5个附加文件;在我们这个例子中,这些文件都是由Jdeveloper向导生成的。首先,是两个 Web服务开发人员很熟悉的文件--WSDL文件EmpService.wsdl,用来用XML描述Web服务接口和参数;web.xml文件,将Web 服务作为一个servlet进行基本配置。
|
下载 OracleAS10g Containers for J2EE(OC4J)的开发人员预览版 使用Oracle JDeveloper 10g JAX-RPC扩展预览版在设计时测试JAX-RPC 通过构建本文示例来了解该循序渐进学习指南中的更多内容 |
EmpService-java-wsdl-mapping.xml文件使这些文件变得更加有趣。对于在Emp.java接口中定义的每一个Java方法及其参数来说,该文件都提供了到相应的WSDL portType(相当于Java接口)、WSDL 操作(相当于Java方法)和WSDL XML消息(相当于Java方法的参数)的映射。
最后两个重要文件是webservices.xml和oracle-webservices .xml。其中,第一个文件说明JAX-RPC映射文件的位置和Web服务端点;第二个文件是专门针对于Oracle的JAX-RPC实现的,为 Oracle的J2EE容器提供额外的绑定信息。将这些配置文件与Emp.java和EmpImpl.java实现文件一起打包成ear (Enterprise Archive)文件之后,它们能够被作为J2EE应用程序部署到Oracle应用服务器,并可被作为Web服务调用。
构建客户端
正像JAX-RPC标准化了J2EE Web服务的服务器端一样,它还提供了一套构建JAX-RPC客户端的标准模型。让我们来看一个典型的静态J2SE承接软件客户端(stub- client)示例,在该示例中,本地客户端充当远程服务的代理。JAX-RPC也支持其他的客户端风格,包括动态代理、动态接口调用和J2EE客户端。
所有Web服务客户端的目标都是以编程方式构建一个遵循Web服务WSDL文件中的规范的SOAP消息。为实现这一目标,JAX-RPC实现提供一个WSDL到Java客户端的生成工具,就像Oracle应用服务器和Oracle Jdeveloper中所提供的工具那样。
清单 2 给出了一个JAX-RPC客户端的例子。承担绝大部分重要工作的Java类是EmpService_Impl.java,它表示由WSDL所定义的Web服务的一个远程实例。与它一起生成的是一个表示由Web服务以Java包类型发送和接收的数据类型的类集,这发生在第9行。在这里,逻辑WSDL端口是由服务代理EmpService_Impl.java返回的,并映射到相同的Java接口EmpInterface.java,该接口被用于实现 EmpImpl.java中的服务。一旦完成这一映射,调用Web服务的实际工作将在第10行完成,在这里远程Web服务的getEmpSalary方法将被调用,数据被返回给变量响应。
关于JAX-RPC的更多内容
在我的下一篇文章中,我将介绍JAX-RPC处理程序以及如何通过SOAP API将各种标题用于Java附加方面的内容。
Mike Lehmann ( mike.lehmann@oracle.com)是OracleAS Containers for J2EE(OC4J)的主要产品经理。