如何利用 Web 服务描述语言 (WSDL) 文档开发 Web 服务

首次发布时间:2004 年 9 月 14 日
最后更新日期:2006 年 1 月 18 日
作者:Jon Maron


简介

Oracle 应用服务器为利用现有 Web 服务描述语言 (WSDL) 文档生成 Web 服务提供了便利。这个自上而下的方法虽然不像自下而上的方法(将现有类公开为 Web 服务)那样简单,但也有许多受欢迎的原因:

利用 WSDL 文档生成 Web 服务并创建关联的客户端应用程序的过程包括:

诚然,可以创建较为简单的参数,使其通过实施 SEI(如上所述消除了创建服务实施类的要求)只需修改底层实施类并将其直接公开为 Web 服务。尽管存在这种可能,但更为普通且常见的情况是,现有类无法修改。相反,还需要在不修改目标类的情况下,将现有类提供的功能公开给远程客户端。我们将在以下示例中探究这个案例。

前提条件

知识准备

软件要求

符号定义

整个文档使用以下约定:

构建应用程序

下面我们将详细了解利用现有 Java 类创建 Web 服务应用程序的步骤。该示例已经执行了这些步骤,这里仅用于演示目的。

现有 Bank 实施

BankMemDB 类是 Bank 接口的实现,它提供了标准的银行业务功能:

该类是我们希望通过 Web 服务接口提供其功能的访问权限的现有类。

Bank 接口的实例(如 BankMemDB)由 BankFactory 创建:

public class BankFactory {
    public BankFactory();
    public Bank createBank();
}

将 Bank 公开为 Web 服务

为了使用自上而下的开发方法将现有 Bank 的实例公开为 Web 服务,我们将执行以下操作:

  1. 利用服务 WSDL 生成服务接口。完整的 WSDL 文件可以在 此处获得。WSDL 文件的以下部分显示了在 SEI 中结束的操作:
   
        A service that provides banking operations for client applications.
       
            Creates a banking account.
           
           
           
       

       
            Performs a bank deposit.
           
           
           
       

       
            Retrieves an account ID.
           
           
           
       

       
            Retrieves an account balance.
           
           
           
       

       
            Withdraws funds from a bank account.
           
           
           
       

   


    利用 WSDL 生成的服务接口表示了我们希望提供给客户端应用程序的功能和操作:

      interface BankService extends java.rmi.Remote{
          String createAccount(String acctName,float initBalance) throws RemoteException, AccountException;
          void deposit(String acctID, float amount) throws RemoteException, AccountException;
          void withdraw(String acctID, float amount) throws RemoteException, AccountException;
          float getBalance(String acctID, String acctName) throws RemoteException, AccountException;
          String getAccountID(String acctName) throws RemoteException, AccountException;
      }

      您将注意到,该服务接口扩展了 java.rmi.Remote 接口,并且所有方法都会引发(至少是)java.rmi.RemoteException 异常(这是 JAX-RPC 规范的要求)。


      1. 创建一个服务实施。实施类 (BankServiceImpl) 将实施服务接口 (BankService),并将各种调用委托给它创建的 Bank 实例。例如,createAccount() 方法只调用底层 Bank 的 addNewAccount() 方法(m_bank 是从 BankFactory 获得的 BankMemDB 的实例):
          public String createAccount(String acctName,float initBalance) throws RemoteException,AccountException {
              return m_bank.addNewAccount(acctName,initBalance);
          }

      创建客户端应用程序

      一旦创建并部署服务之后,就可以利用 WSDL 文件(作为服务生成过程的一部分而生成)创建利用该服务的客户端应用程序(请参阅 生成、编译和部署应用程序)。

      除了 JAX-RPC 运行时需要的类,Oracle 应用服务器的客户端生成工具还会创建一个方便类,使开发人员从某些较为琐碎的 JAX-RPC 服务实例化任务中解脱出来。该类称为实用程序客户端,银行业务应用程序 (BankApplication) 将利用该类调用远程服务上的方法( m_endpoint 是该实用程序客户端的类属性):

              void demoGoodAccount() throws Exception {
              String accountID = m_endpoint.createAccount(DEMO_USER1,2000.50f);
              // ... print statements removed for clarity ...
              m_endpoint.deposit(accountID,500.50f);
              float balance = m_endpoint.getBalance(accountID,DEMO_USER1);
              System.out.println("Current balance is now " + balance);
              System.out.println("Withdrawing $250.00 from account");
              m_endpoint.withdraw(accountID,250.00f);
              balance = m_endpoint.getBalance(accountID,DEMO_USER1);
          }

      上述组件的 javadoc 可以从 此处获得。

      如果给定 Bank 实施与支持类、服务接口和服务实施,我们就可以继续生成和部署 Web 服务了。

      运行示例

      在本例中,我们将创建一个将其功能包装并委托给底层 Bank 对象的银行 Web 服务。

      检查方法文档分发

      方法文档 zip 文件应包含以下内容:

      设置应用程序

      请检查以确保以下属性在示例分发根目录下的 ant-oracle.properties 文件中配置正确(注意:某些属性将默认为相应环境变量的值,如下所示。如果您已经在环境中设置了这些变量,则不必在文件中更改这些值)。如果有必要,将这些变量修改为环境的相应值:

      此外,请确保与 OC4J ant 版本关联的 ant 命令位于执行路径 ( %ORACLE_HOME%/ant/bin) 中。

      为受管理的 OracleAS 实例配置环境

      如果您运行的是 Oracle 应用服务器 10 g 的受管理版本,并且要使用 OPMN,则必须更改以下值以符合您的配置:

      此外,请确保与 OC4J ant 版本关联的 ant 命令位于执行路径 ( %ORACLE_HOME%/ant/bin) 中。

      运行 OC4J 实例

      g
      • 独立安装: %ORACLE_HOME%/bin/oc4j start
        注意, oc4j 命令期望 JAVA_HOME 环境变量指向整个 JDK 安装。

      • OracleAS 受管理的安装: %ORACLE_HOME%/opmn/bin/opmnctl startall


      生成、编译和部署应用程序

      要生成、编译和部署该应用程序的组件,只需在示例根目录的命令提示符下键入以下命令:

      要执行所提供的 build.xml 文件中默认的“所有”目标,请执行以下步骤:

                  output="${src.webservice.dir}"
                  packageName="topdown.service">
                 
                     
                 

             


      • 编译 src/service 子目录中的所有 Web 服务源文件(银行和服务接口与实施)。
      • 创建部署所需的服务产物(JAX-RPC 映射文件等)。这些文件是通过 topDownAssemble ant 任务生成的:
                  wsdl="${src.webservice.dir}/bank.wsdl"
                  className="topdown.service.BankServiceImpl"
                  input="${bld.webservice.dir}"
                  output="${out.dir}"
                  ear="${lib.dir}/${ear.name}.ear">
                 
                     
                 

             



      • 部署应用程序模块。现在,使用 ant deploy ant 任务将上一步中生成的 .ear 文件部署到服务器:
                      host="${oc4j.host}"
                  port="${oc4j.admin.port}"
                  userId="${oc4j.admin.user}"
                  password="${oc4j.admin.password}"
                  file="${lib.dir}/${app.name}.ear"
                  deploymentName="${app.name}"
                  logFile="deploy-ear.log"/>



                          host="${oc4j.host}"
                  port="${oc4j.admin.port}"
                  userId="${oc4j.admin.user}"
                  password="${oc4j.admin.password}"
                  webModule="${web.name}"
                  webSiteName="${oc4j.binding.module}"
                  contextRoot="/${app.name}"/>
      • 创建客户端代理源文件。一旦服务被部署并且可用,就可以通过可用的 WSDL 文件生成客户端代理(通过使浏览器指向 http://<OC4J host>:<OC4J http port>/bank/bank?wsdl 位置,您可以实际看到生成的 WSDL 服务文件)。 genProxy ant 任务就用于实现此目的:
                      output="${src.cli.dir}"
                  packageName="topdown.client.proxy"
                  >
                 
                     
                     
                 

             


      • 编译客户端应用程序和关联的代理文件。您需要编译上一步中生成的代理文件以及利用代理进行远程通信的客户端应用程序,并将它们放到 build/bank/bank-client 目录中。

      运行应用程序

      现在,Web 服务已经部署,并且客户端已经生成并编译,下面我们就可以运行应用程序了。从示例根目录的命令提示符下,只需键入以下命令即可:

      该命令执行的客户端应用程序将执行以下操作和信息交换(下面的信息交换图是由 JDeveloper 10g TCP Packet Monitor 捕获的,用于说明在执行远程服务调用期间执行的底层信息交换):



      run:
              [java] Created an account for DemoUser1 with $2000.50
              [java] AccountID for DemoUser is 138.2.8.242_DemoUser1
              [java] Depositing $500.50 into account.
              [java] Current balance is now 2501.0
              [java] Withdrawing $250.00 from account
              [java] Attempting to create an account for DemoUser2 with no initial funds
              [java] Could not createAccount for DemoUser2
              [java] Insufficient funds for new account.  You must start an account with more than $0
              [java] Created an account for DemoUser3 with $3000.00
              [java] Attempting to withdraw 2500.00 from the account.  The account cap is 2000.00
              [java] Unable to withdraw funds.
              [java] Exceeded maximum withdrawal of $2000.00

          BUILD SUCCESSFUL

      总结

      该方法文档详细说明了如何利用 WSDL 文档生成 Web 服务。我们已经看到该过程包括:

Left Curve
热门下载
Right Curve