内容


用 DB2、Visual Basic .NET 和 Java 构建 Web 服务

Comments

教程简介

概述

本教程演示了如何结合 Visual Basic .NET Web 服务与基于 Web 的 Java 应用程序来访问 DB2 数据库中的数据。

在本教程中,您将学习下列内容:

  • 如何使用 DB2 Development Add-in 来创建数据库对象和存储过程
  • 如何在 Visual Basic .NET 中创建 Web 服务
  • 如何向 UDDI 服务器注册 Web 服务
  • 如何用 Java 构建访问 Web 服务的简单应用程序

本教程中的样本应用程序围绕着一个 Web 服务,该服务为 JustPC.com Airlines 跟踪常旅客里程。数据存储在 DB2 数据库中,使用 DB2 管理的提供程序可以从 Visual Basic .NET Web 服务访问该数据库。基于 Java 的 Web 程序访问该 Web 服务来验证一位特定的客户是否已在常旅客计划中登记,并且还可以增加和扣除里程。

附带 DB2 Development Add-in 的 Microsoft Visual Studio .NET 可用来创建 DB2 数据库对象,以及创建 Visual Basic .NET Web 服务。IBM WebSphere Studio Application Developer 可用来创建访问 Web 服务的 Web 工程。

教程对象

如果符合以下情况之一,则应该学习本教程:

  • 您熟悉 DB2 并希望了解如何使用新的 DB2 管理的提供程序来创建 Visual Basic .NET Web 服务。
  • 您熟悉 Visual Basic .NET 并希望了解如何使用新的 IBM DB2 管理的提供程序来访问 DB2 数据库。
  • 您熟悉 Visual Studio .NET 并希望了解如何使用 DB2 Development Add-in 来创建 DB2 数据库对象。
  • 您对非 Microsoft 数据库可以多么完美地集成到 .NET 应用程序中感到好奇。
  • 您对 Visual Basic .NET 和 Java 如何可以并存在单个应用程序中感到好奇。

工具

本教程使用 IBM 和 Microsoft 的软件。

  • IBM WebSphere Application Developer 可用来创建 Java Web 程序。从这里您可以下载其评估版副本。
  • Microsoft Visual Studio .NET(http://msdn.microsoft.com/vstudio/)提供了用以构建 Visual Basic .NET Web 服务的开发环境。
  • Microsoft Windows 2000 Server(http://www.microsoft.com/windows2000/server/)是主管 DB2 的操作系统,它还提供运行 Web 服务和 C# ASP.NET 应用程序的工具。请注意,您也可以使用 Windows 2000 Advanced Server、Windows 2003 Server 或 Windows 2003 Advanced Server。
  • 数据库服务器所在的机器上还必须有用来编译存储过程的独立的 C 编译器。您应该参考 DB2 安装文档以获取更多详细信息。

:尽管本教程是在单个 Windows 2000 Server 系统上创建和测试的,但您可以选择在 Windows 2000 或 XP Professional 系统上运行 Visual Studio .NET,然后将相应的文件复制到 Windows Server 系统上以便执行。

您也可以下载本教程所有的 ZIP 格式文件(52 KB)。

声明和商标

Copyright, 2003 International Business Machines Corporation. All rights reserved.

IBM、DB2、DB2 Universal Database 和 IBM WebSphere Application Developer 是 IBM 公司在美国和/或其他国家或地区的商标或注册商标。

Microsoft、Windows 和 Windows 2000 是 Microsoft Corporation 在美国和/或其他国家或地区的注册商标。

其他公司、产品和服务名称可能是其他公司的商标或服务标记。

理解应用程序

概述

JustPC.com Airline 维护着一个包含其客户和他们所获得的常旅客里程信息的数据库。因为许多其他组织与 JustPC.com Airlines 合作进行常旅客计划,所以他们实现了一个 Web 服务来为其他组织提供访问常旅客信息的标准方法。

常旅客信息存储在一个 DB2 数据库中。Visual Basic .NET Web 服务通过一系列的存储过程来访问此数据库中的信息。接着将由 Java Web 应用程序访问 Web 服务,并将信息呈现给最终用户。

数据库设计

该数据库由三张表构成:一张表包含一列客户,一张表包含一列机构,以及一张事务表。

Customers 表包含三个列:CustomerId 列包含数据库中每位客户的唯一标识;CustomerName 列包含客户的名称;以及 Miles 列,它包含常旅客里程的总数。

图 03
图 03

Agencies 表包含三个列:Agency 列唯一标识可以访问 Web 服务的组织;AddMiles 列在允许该机构添加常旅客里程时为 true;以及 SubtractMiles 列,在允许该机构减去常旅客里程时为 true。

图 04
图 04
图 04

CustomerTransactions 表包含四个列:TransactionDate 列包含更新发生的日期和时间;CustomerId 列唯一标识特定的客户;Agency 列唯一标识进行更改的组织;以及 Miles 列,它包含从总数添加或减去的里程数。

Visual Basic .NET Web 服务

该 Web 服务提供了三种方法来访问数据库中的数据:

  • GetCustomerById 方法返回单个客户的信息。这个方法有两个输入参数,CustomerId 包含与客户关联的 ID 值,而 Agency 标识请求此信息的组织。根据这些值,此方法返回数个其它参数,包括 CustomerNameTotalMiles
  • CreditMiles 方法把指定的里程数添加到指定客户的可用总里程数中。这个方法有四个输入参数:CustomerIdMilesAgencyTransactionId
  • DebitMiles 方法与 CreditMiles 方法类似,只不过它是从客户的总里程数中减去指定的里程数。

DB2 存储过程

由 Web 服务使用来访问数据库的存储过程反映了与该 Web 服务关联的方法。

  • GetCustomerById 存储过程根据 CustomerId 值返回关于特定客户的信息。
  • UpdateMiles 存储过程更新与此客户关联的常旅客里程数。

Java Web 程序

为了演示该 Web 服务的能力,我编写了一个简单的 JavaServer Page(JSP)。这个程序调用了前几页中讨论的全部三个 Web 服务方法,并允许该 Web 站点的访问者检索关于特定客户的信息,以及添加或减去常旅客里程。

构建数据库

创建 DB2 数据库工程

要创建 JustPC.com Airline Company 的数据库,请启动 Microsoft Visual Studio .NET(开始 => 程序 => Microsoft Visual Studio .NET => Visual Studio .NET)并单击 New Project 按钮。在 New Project 对话框中,选择 DB2 Database Project。给于该工程一个有意义的名称并指定您想要保存该工程的目录。

连接 Airline 数据库

在创建 DB2 数据库工程之后,将提示您选择数据库连接。如果您已经创建了一个连接,您可以在 Connection Name 下拉框中选择它。否则,请按 New Connection 按钮并在 Database Connection Information 对话框中输入信息。单击 Test Connection 按钮以验证您输入的信息是否正确。

创建 Customers 表

一旦建立了到数据库的连接,DB2 Development Add-in 将自动地载入关于在该数据库中存储的表、视图和存储过程的信息。它也标识了所有与这个工程关联的源文件并使它们在 Solution Explorer 窗口(显示在 Visual Studio .NET IDE 的右侧)中可用。

要将 Customers 表添加到数据库,请右键单击 Solution Explorer 中的 Scripts 节点并从上下文菜单选择 Add => Add New Item。在 Add New Item 对话框中,在 Categories 节中选择 Scripts,并在 Templates 节中选择 Create Table。接着,在 Name 文本框中指定此脚本文件的名称,然后单击 Open 按钮来创建一个新的 Create Table 模板。

修改 Create Table 模板

Create Table 模板包含了一组 SQL 语句,您可以对语句加以修改以符合您自身的情况。此脚本执行四个主要的功能。第一,脚本从数据库中删除表。第二,Create Table 语句构建该表。第三,Create Index 语句将一个唯一索引应用到该表。第四,一系列 Insert 语句向最新创建的表添加数据。

请考虑将删除表的语句注释掉,使得一旦表包含有效数据便不会被意外地删除。这意味着如果该表已存在,Create Table 语句将会失败,而脚本余下的部分也将不会执行。

您可以使用以下的 Create Table 语句来构建 Customers 表。

CREATE TABLE Customers
(CustomerId    Int Not Null,
 CustomerName  Varchar(255),
  Miles        Int)

然后以下 Create Index 语句确保 CustomerId 值是唯一的。

CREATE UNIQUE INDEX CustomersIndex ON Customers(CustomerId)

最后,以下 Insert 语句向该表添加一些样本数据。

INSERT INTO Customers VALUES (1,'John', 0)
@
INSERT INTO Customers VALUES (2,'Smith', 0)
@
INSERT INTO Customers VALUES (3,'James', 0)

创建 Agencies 和 CustomerTransactions 表

在完成 Customers 表的 Create Table 脚本之后,您可以使用相同的技术为 Agencies 和 CustomerTransactions 表创建新的脚本。您可以使用以下的 Create Table 语句来创建 Agencies 表。

CREATE TABLE Agencies
  (Agency       Varchar(255)NOT NULL,
  AddMiles      Int,
  SubtractMiles Int)

而以下语句可以用来创建 CustomerTransactions 表。

CREATE TABLE CustomerTransactions
 (TransactionId    Int Not Null,
  CustomerId       Int,
  TransactionDate  Date,
  Agency           Varchar(255),
  Miles            Int)

构建表

在完成这三个脚本文件之后,通过在 Solution Explorer 窗口中选择解决方案和从 Visual Studio .NET 主菜单选择 Build => Build Solution,您可以创建所有的数据库表。通过在 Solution Explorer 窗口中选择您想要运行的脚本,并从主菜单选择 Build => Compile,您还可以分别运行每个脚本。

在编译脚本的过程中,生成的任何错误消息都会显示在 Output 窗口中,该窗口位于 Visual Studio .NET IDE 的底部。在 Output 窗口中选择 IBM DB2 Output Message Pane,这样将允许您查看编译过程的全部详细信息。

查看表的内容

有一个功能您可能会觉得有用,那就是无须启动其它程序即可浏览数据库表的内容的能力。要查看一张表,请切换至 IBM Explorer 窗口(从主菜单选择 View => IBM Explorer)并展开 Tables 图标以显示数据库中表的列表。右键单击您想要查看的表名并从弹出菜单选择 Retrieve Data From Table。该表的内容将会显示如下:

您还可以在 IBM Explorer 窗口中浏览数据库的结构。例如,通过在树状结构中展开特定的表,您可以查看该表的每一列,而如果您选择特定的列,您可以在 Properties 窗口中查看其详细信息。

创建 DB2 存储过程

启动存储过程向导

在大多数数据库服务器中,存储过程是访问数据的首选方法,而 DB2 也不例外。DB2 Development Add-in 为 Visual Studio .NET 开发者提供了必要的工具,让他们无须退出 Visual Studio .NET IDE 即可构建存储过程。

要创建存储过程,请切换至 Solution Explorer,右键单击 Procedures 图标并从弹出菜单选择 Add => Add New Item。在 Add New Item 对话框中,在 Categories 窗口中选择 Procedures,然后选择 DB2 Stored Procedure Wizard 模板。在输入将会保存该存储过程的源代码的文件名之后,请按 Open 按钮来启动存储过程向导。

命名存储过程

当该向导首次启动时,它将会显示一个 Web 面板以提示您正在构建 SQL 存储过程。在按 Next 之后,存储过程向导的第一步出现并提示您输入此存储过程的名称。您还可以在 Comment 区域中描述此存储过程。

添加语句

在该向导的第 2 步中,您被提示为存储过程输入 SQL 语句,每次一条语句。每条语句都分配一个名称以简化编辑过程。通过在 Order 字段调整其值,您可以将语句移动自如。

在此过程中,因为特定的 CustomerId 值只可能对应一位客户,所以无需返回多行数据。因而可以通过参数将数据返回至存储过程,与返回单个行的数据并在应用程序中从该行抽取信息的方法相比,这样做的效率会高得多。

在您输入每条语句时,通过在参数的名称前加上冒号(:),您可以引用任何将被传送到存储过程的参数。

定义参数

该向导的下一步会提示您每个参数的定义 - 这些参数是您把语句输入到存储过程中时所使用的。IdTotMiles 参数是 Integer,而 CustName 参数是 Varchar(255)。要更改数据类型,只须从 Type 下拉列表选择适当的类型。根据类型可能会显示 Length、Precision 和 Scale 附加字段,使您可以指定该参数的其它特性。

Mode 字段允许您指定该参数的数据方向。在缺省情况下,Mode 设置为 In,指数据被发送到存储过程。您也可以指定 Mode 为 OutInoutOut 意味着该参数只在存储过程执行完后才包含有效数据,而 Inout 是指数据可以传送到存储过程,也可以由存储过程返回。

由于 CustNameTotMiles 参数包含从存储过程返回的信息,因此您可以将 Mode 选择为 OutInout。然而,建议您选择 Inout,因为您可以在调用存储过程前初始化参数,这样可以有助于同时在存储过程和应用程序中防止未初始化变量的问题。

完成向导

向导中剩余的步骤为您提供了选项以从外部文件插入标准化的代码片段,并指定出错处理的类型。还为您提供了选项来让向导生成在 Create Procedure 语句之前执行的 Drop Procedure 语句,和在 Create Procedure 语句之后执行的 Grant 语句。全部这些选项的缺省值都适用于本教程。

该向导的最后一步包含您选定的选项的总结,而且能够预览生成的脚本。最好能在按 Finish 按钮之前检查这些信息。如果您找到任何错误,请按 Back 按钮以在向导中回退至包含您想要更改的信息的步骤。

一旦您确信全部这些信息都是正确的,请按 Finish 按钮来生成包含存储过程的脚本文件。请注意,按 Finish 按钮并不会创建存储过程本身。而只是生成在您返回到 Visual Studio .NET IDE 时可以编译的脚本文件。

编译存储过程

在您可以编译这个特定的存储过程之前,您需要对脚本进行一些次要的修改。因为向导假定您想要将一组行返回至应用程序,所以存储过程中包含一些多余的代码。具体地讲就是您需要删除 Declare Cursor 语句,而只留下 Select 语句。然后您需要删除任何 Open 和 Close 语句。

在编辑脚本之后,您可以通过从 Visual Studio .NET 主菜单选择 Build=>Compile 来编译它。如果脚本被正确地编译,您将会在 Output 窗口中看到一条消息显示编译成功。

测试存储过程

DB2 Development Add-in 包含一个工具,您可以用它来测试您的存储过程而无需构建应用程序。切换至 IBM Explorer 窗口,右键单击 Procedures 图标并从上下文菜单选择 Refresh。这会使得 DB2 Development Add-in 从数据库获取关于存储过程的最新信息。

展开 Procedures 图标,将显示您刚添加的存储过程。右键单击该存储过程并从弹出菜单选择 Run Stored Procedure。如果该存储过程包含任何参数,将会提示您为每个参数输入值。

图 16

图 16

单击 OK 按钮,将会启动该存储过程并在主 Visual Studio .NET IDE 窗口中显示其结果。请注意,您将必须展开此结果并浏览至如下所示的 Output 数据集:

更新数据库

由于需要验证该机构是否有权更新数据库以及需要在 CustomerTransactions 表中记录所有更新,所以用以更新数据库的存储过程有些复杂。您可以使用和您用于 GetCustomerById 存储过程一样的步骤来创建、编译和测试这个存储过程。

这个例程从使用 Select Into 语句来检索授权信息放入一些本地变量开始。然后它检查该能力以及 NewMiles 参数标记来验证执行的更新是否正确。

如果该事务是合法的,则使用 Update 语句来更新客户的常旅客里程,同时执行 Insert 语句来把更新记录到 CustomerTransactions 表中。然而,如果该事务不合法,则将 TransId 设置为 -1,表明没有发生任何更新:

CREATE PROCEDURE ADMINISTRATOR.UPDATEMILES(
   IN      CustId            INTEGER,
   IN      NewMiles          INTEGER,
   INOUT   TransId           INTEGER,
   IN      TransDate         DATE,
   IN      UpdateAgency      VARCHAR(255))

SPECIFIC ADMINISTRATOR.UPDATEMILES

P1: BEGIN

Declare Ok2Add Int Default 0;
Declare Ok2Sub Int Default 0;

Select AddMiles, SubtractMiles
   Into Ok2Add, Ok2Sub
   From Agencies
   Where Agency = UpdateAgency;

If ((Ok2Add = 1) And (NewMiles > 0)) Or ((Ok2Sub = 1) 
   And (NewMiles < 0)) then Update Customers
      Set Miles = Miles +  NewMiles
      Where CustomerId =  CustId;

   Insert 
      Into CustomerTransactions(
         TransactionId, 
         CustomerId, 
         TransactionDate, 
         Agency,
         Miles)
      Values(
         TransId, 
         CustId, 
         TransDate, 
         UpdateAgency, 
         NewMiles);

    Commit;
    
 Else
    Set TransId = -1;

 End If;

END P1

构建 Visual Basic .NET Web 服务

在 Visual Studio .NET 中创建 Web 服务工程

当仍在 Visual Studio .NET 中时,从主菜单选择 File => Add Project => New Project 来向您当前的解决方案中添加 Visual Basic .NET Web 服务工程。您将看到 Add New Project 对话框,如下所示:

在 Project Types 中选择 Visual Basic Projects,然后在 Templates 中选择 ASP.NET Web Service。接着,选择 Web 服务的位置。最后,单击 OK 按钮来创建新的 Web 服务。这个模板将构成新的 Web 服务的基础。

重命名 Web 服务

在缺省情况下,Visual Studio .NET 分配给新的 Web 服务的名称为 Service1。应该更改这个名称来反映它的用途。要重命名 Web 服务,请在 Solution Explorer 中右键单击该文件名并从上下文菜单选择 Rename。将文件名更改为 AirlineMiles.asmx

把 DB2 库添加到解决方案

为了访问 DB2 数据库,您需要将 DB2 管理的提供程序添加到您的应用程序。右键单击 References 图标并从上下文菜单单击 Add Reference 来显示 Add Reference 对话框。浏览 Component Names 列表直到您看到 IBM.Data.DB2.dll。选择这个组件,然后单击对话框右侧的 Select 按钮。选定组件会出现在对话框的 Selected Components 部分中。最后,单击 OK 来将引用添加到您的 Web 服务工程:

在将库添加到这个解决方案之后,您还应该将下列语句添加到 Web 服务的开头。Imports 语句会简化编程,因为您无需完全限定类的名称。所以您可以输入 DB2Connection 而不必输入 IBM.Data.DB2.DB2Connection

Imports IBM.Data.DB2

定义 Web 服务

Web 服务可实现为一个单独的类,这个类带有一系列的方法来执行各种任务。Class 语句之前的是将此类标记为 Web 服务的属性。在缺省情况下,与 Web 服务关联的名称空间是 http://tempuri.org。然而,由于 Web 服务的名称在名称空间中必须是唯一的,因而强烈建议您将名称空间更改为特定于您的组织的空间。

<WebService(Namespace:="http://justpc.com/", _
   Description:="Manipulates frequent flyer milage for JustPC.com Airline")> _
Public Class AirlineMiles
   Inherits System.Web.Services.WebService

请注意,WebService 属性实际上是 Class 语句的一部分,所以如果该语句跨越数行,则需要在每行的结尾添加一个空格和一道下划线。

定义 GetCustomerById Web 方法

Web 方法只是能够从使用 Web 服务的应用程序中调用的子例程或函数。为了将一个例程标记为 Web 方法,您需要包含如下所示的 WebMethod 属性。CustomerNameTotalMiles 参数都被标记为 ByRef,这是由于数据库中的数据通过这些参数被返回到调用的程序:

<WebMethod()> _
Public Sub GetCustomerById(ByVal CustomerId As Integer, _
   ByRef CustomerName As String, ByRef TotalMiles As Integer)

Dim conn As New DB2Connection("database=Airline")
Dim cmd As New DB2Command("Administrator.GetCustomerById", conn)

Try
   cmd.CommandType = CommandType.StoredProcedure
   cmd.Parameters.Add(":CustId", DB2Type.Integer).Value = CustomerId
   cmd.Parameters.Add(":CustName", DB2Type.VarChar, 255).Value = ""
   cmd.Parameters(":CustName").Direction = ParameterDirection.InputOutput
   cmd.Parameters.Add(":TotMiles", DB2Type.Integer).Value = -1
   cmd.Parameters(":TotMiles").Direction = ParameterDirection.InputOutput

   cmd.Connection.Open()
   cmd.ExecuteNonQuery()
   cmd.Connection.Close()

   CustomerName = cmd.Parameters(":CustName").Value
   TotalMiles = cmd.Parameters(":TotMiles").Value

Catch ex As DB2Exception
   CustomerName = ex.Message
   TotalMiles = -1

End Try

End Sub

例程中创建了连接到 Airline 数据库的 DB2Connection 对象。然后创建了 DB2Command 对象来引用 GetCustomerById 存储过程和最新创建的连接对象。

Try 语句被用来捕获任何可能出现的数据库错误。如果出现一个错误,则将 TotalMiles 设置为 -1,而错误消息在 CustomerName 参数中返回。

Try 语句中的数据库代码是一目了然的。命令对象的 CommandType 属性被设置为 StoredProcedure。然后,存储过程的每个参数都被添加到命令对象的 Parameters 集合。在缺省情况下,每个参数都标记为 Input,所以有必要将 CustNameTotMiles 参数标记为 InputOutput,因为它们包含来自存储过程的结果。

一旦定义了所有参数,则到数据库的连接被打开,然后执行存储过程并关闭连接。最后,由存储过程返回的值被复制到 Web 方法的 ByRef 参数中,这样数据可以返回到调用的程序。

定义 CreditMiles Web 方法

CreditMiles Web 方法的代码与 GetCustomerById Web 方法的十分相似。在这种情况下,任何错误都会通过 TransactionId 参数传送回调用的程序。值 -1 表示有一个数据库错误,而值 -2 表示传送到该方法的里程数是无效的。

<WebMethod()> _
Public Sub CreditMiles(ByVal CustomerId As Integer, ByVal Miles As Integer, _
   ByVal Agency As String, ByRef TransactionId As Integer)

Dim conn As New DB2Connection("database=Airline")
Dim cmd As New DB2Command("Administrator.UpdateMiles", conn)

If Miles < 0 Then
   TransactionId = -2

Else
   Try
      cmd.CommandType = CommandType.StoredProcedure
      cmd.Parameters.Add(":CustId", DB2Type.Integer).Value = CustomerId
      cmd.Parameters.Add(":NewMiles", DB2Type.Integer).Value = Miles
      cmd.Parameters.Add(":TransId", DB2Type.Integer).Value = TransactionId
      cmd.Parameters.Add(":TransDate", DB2Type.Date).Value = DateTime.Now
      cmd.Parameters.Add(":Agency", DB2Type.VarChar, 255).Value = Agency

      cmd.Connection.Open()
      cmd.ExecuteNonQuery()
      cmd.Connection.Close()

   Catch ex As DB2Exception
      TransactionId = -1

   End Try

End If

End Sub

如在 GetCustomerById 中一样创建 DB2ConnectionDB2Command 对象。同样的技术被用来定义 UpdateMiles 存储过程的参数。请注意,与 GetCustomerById 不同的是,因为与 UpdateMiles 关联的所有参数都只是输入,所以无须显式定义参数的方向,也无须在存储过程完成之后从参数复制任何值。

完成 Web 服务

DebitMiles Web 方法的代码与 CreditMiles Web 方法的几乎是相同的,除了 :NewMiles 参数中传送的里程数是负数,这样将从客户的总里程数中减去(而不是向其中添加)该里程数。

在完成编码后,您可以通过从菜单栏选择 Build => Build Solution 来编译您的 Web 服务。如果您的程序能正确地编译,您将会在 Output 窗格中看到成功的消息,否则 Output 窗格将会显示一系列编译器错误,在您可以使用此 Web 服务之前必须更正这些错误。

验证 Web 服务

一旦 Web 服务编译完成,您可以通过打开 Web 浏览器并输入该 Web 服务的位置来验证它已经正确地安装。这样会显示该 Web 服务的一段简短描述,如下所示:

您可以通过单击 Service Description 超级链接来显示包含 Web 服务描述语言(Web Service Description Language,WSDL)的原始 XML 文档。单击任一 Web 方法超级链接将会显示描述 SOAP 请求和响应的 XML 文档。

注册 Web 服务

IBM UDDI 业务测试注册中心

IBM 为开发者提供了统一描述、发现和集成(Universal Description, Discovery and Integration - UDDI)注册中心(https://uddi.ibm.com/testregistry/registry.html),开发者可以在其中注册他们的 Web 服务以便进行测试。您可以搜索 UDDI 目录以查找 Web 业务和 Web 服务,或输入您自己的。为了输入您自己的 Web 服务,您将需要有效的 IBM UDDI User ID 和 Password,这些您可以轻松地从该 Web 站点获取。

向 UDDI 注册中心添加业务

在您可以在 UDDI 注册中心发布您的 Web 服务之前,您需要首先添加您的业务。在登录注册中心之后,单击 Add a New Business 超级链接来开始添加有关您的业务的信息。

将业务添加到 UDDI 注册中心的第一步是指定业务的名称及其缺省语言。一旦您输入这些信息,请按 Continue 以转至过程的下一步。

一旦输入了业务名称,您可以提供关于该业务的其它信息,包括业务描述、业务联系信息和位置的列表。请注意,每个字段都可以有多个项,而每项都以不同的语言表示。这使得全球各地的人们都能更方便地查找到您的 Web 服务。

一旦您已输入所有您想要提供的信息,请按该 Web 页面底部的 Continue 按钮。然后您将看到另一个页面,其中您可以检查您提供的信息。如果信息准确无误,请按 Save 按钮来将信息保存到数据库。一旦信息保存完毕,请按 Continue 以返回到主菜单。

添加新的 Web 服务

要查看与您的业务关联的 Web 服务列表,请单击您的业务名称左侧的 + 图标。这样会展开关于您的业务的信息,并列出与其关联的所有 Web 服务。要添加新的 Web 服务,请单击 Add a New Service 超级链接。

在单击 Add a New Service 之后,将会提示您输入 Web 服务的名称。选择一种语言,输入您的 Web 服务的名称,并按 Continue 以转至下一个页面。这里包含 Web 服务的描述和一个可以用以访问该 Web 服务的访问点。您甚至可以指定其它信息来帮助其他人找到您的 Web 服务。

当您完成输入这些信息后,请按 Continue 来检查您的信息,然后按 Save 来将信息保存到数据库。

查找 Web 服务

既然您已将 Web 服务的信息输入到 UDDI 注册中心,那么您可以使用 Web 站点上可用的工具来查找 Web 服务。单击页面左侧的 Find 超级链接会使您转至如下所示的 Web 页面。您可以搜索业务、服务以及技术模型,同时可有选择地指定类别信息。还可以使用高级搜索。

由于我们要查找的是与 JustPC.com Airlines 关联的 Web 服务,那么将 justpc.com 输入到搜索字段中并按 Find

UDDI 注册中心搜索会返回以 JustPC.com 开头的所有服务。您可以通过单击 Web 服务的名称来查看关于该 Web 服务的详细信息,或者您可以通过单击业务的名称来查看关于拥有该 Web 服务的业务的详细信息。

关于服务的详细信息包含了您为添加 Web 服务到您的应用程序所需的全部信息。Access Point 字段中包含的超级链接可以用来定位 WSDL(需要它将 Web 服务添加到您的应用程序)。

访问 Web 服务

创建 Web 服务客户机

该 Java 程序是用 IBM WebSphere Studio Application Developer 5.0 创建的。要启动 WebSphere Studio Application Developer 5.0,请选择 开始 => 程序 => IBM WebSphere Studio => Application Developer 5.0。一旦启动了 WebSphere Application Developer,请从主菜单选择 File => New => Other 来显示如下所示的向导:

在向导的左窗格中选择 Web Services,然后在右窗格中选择 Web Service Client。单击 Next 来开始创建 Web 服务客户机。

发现 Web 服务

在该向导的下一步中,请选择 Java proxy 并选中 Test the generated proxy 复选框。然后单击 Next 按钮来为您刚创建的 Visual Basic .NET Web 服务选择 WSDL。在提示处输入 Web 服务的超级链接并追加 ?WSDL。通过指定这个参数,该 Web 服务将自动地为 WebSphere Application Developer 生成必要的 WSDL。

创建 Web 服务代理

Web Service Client 向导的下一步允许您指定各种选项,这些选项将会在构建 Web 服务代理时用到。除了 Project 之外的所有选项都可以使用其缺省值。在 Project 字段中输入工程(它将包含由该向导生成的 Java bean)的名称。然后单击 Finish 来创建 Web 服务代理。

测试 Web 服务代理

创建 Web 服务代理的过程将需要几分钟。当完成该向导后,WebSphere Application Developer 将显示一个 Web 程序,您可以使用它来测试 Web 服务。在 Methods 框架中选择 GetCustomerById (com.justpc.GetCustomerByIdElement) 超级链接。这将会显示由 Web 服务接受的输入参数并带有文本框,您可以在文本框中输入将要传送至 Web 服务的值。

在每个字段输入适当的值之后,请单击 Invoke 按钮来将请求发送至 Web 服务。Web 服务的响应将会显示在 Result 框架中。

构建 Java Web 应用程序

创建 JSP 文件

在完成 Web 服务客户机程序之后,您可以开始构建 JavaServer Page(JSP)。从主菜单选择 File => New => Other。然后从弹出对话框选择 Web => JSP File。单击 Next 以显示向导的 New JSP File 步骤。输入将要保存与该工程关联的文件的文件夹名称,然后输入 JSP 文件的名称。最后,单击 Finish 来创建该 JSP 文件。

编码 Web 页面

当完成该向导时,您将发现它为您留下一个基本模板来创建您的 JSP。这个模板包含所有必要的头信息,也就是说您可以将重点集中在位于文档主体中的代码和 HTML 标记上。

构建 Web 应用程序的第一步是包含对您刚构建的 Web 服务代理的引用。jsp:useBean 标记被用于引用该 Web 服务代理。一经定义,您可以通过使用 id 属性中定义的名称(在本示例中为 AirlineMiles)来引用该 Web 服务:

<jsp:useBean id="AirlineMiles" scope="session" 
class="proxy.soap.AirlineMilesProxy" />

下一步是定义 FORM 标记,它包括了 Web 页面所显示的全部字段。ACTION 属性引用将会处理提交请求的 Web 页面的名称。为简便起见,ACTION 引用本 JSP 页面:

<FORM METHOD="POST" ACTION="AirlineApp.jsp">

定义变量

在窗体中,变量被定义来保留将要传送至 Web 服务的值。每个变量都初始化为已知的缺省值:

<%
String CustomerNameParm = "";
int CustomerIdParm  = 0;
int TotalMilesParm  = -1;
int AddMilesParm = 0;
int SubtractMilesParm = 0;
int TransactionIdParm = 0;
String AgencyParm="JustPC.com Airline";

该窗体包含三个按钮,用户可以单击它们来将信息提交给服务器。为了标识哪个按钮被单击,下列几行代码声明了与每个按钮对应的变量。如果变量的值不为 null,则被按下的是这个特定的按钮。null 值意味着此按钮未被按下:

String
GetCustomerButton = request.getParameter("GetCustomer");
String AddMilesButton = request.getParameter("AddMiles");
String SubtractMilesButton = request.getParameter("SubtractMiles");

定义窗体

该窗体实质上是一个大型的表,其中根据 TotalMilesParm 变量的值而省略了选定的行。customerId 字段始终显示,而如果用户输入一个值并按 GetCustomer 按钮,则将从表中检索关于新客户的信息。如果与此客户关联的总计里程不为负数,那么将显示其余字段。

<H1>JustPC.com Airlines</H1> 
<TABLE> 
<TR> 
<TD COLSPAN="2" ALIGN="LEFT">Frequent Flyer Information:</TD> 
<TR> 
<TD WIDTH="5%"></TD> 
<TD COLSPAN="1" ALIGN="LEFT">Customer id:</TD> 
<TD ALIGN="left"><INPUT TYPE="TEXT" NAME="customerId"  
SIZE=20 VALUE="<%=CustomerIdParm%>"></TD> 
</TR> 
<% 
if (TotalMilesParm >= 0) 
   { 
%> 
<TR> 
<TD WIDTH="5%"></TD> 
<TD COLSPAN="1" ALIGN="LEFT">Customer name:</TD> 
<TD ALIGN="left"><INPUT TYPE="TEXT" NAME="customerName"  
 SIZE=20 VALUE="<%=CustomerNameParm%>"></TD> 
</TR> 
<TR> 
<TD WIDTH="5%"></TD> 
<TD COLSPAN="1" ALIGN="LEFT">Total miles:</TD> 
<TD ALIGN="left"><INPUT TYPE="TEXT" NAME="totalMiles" SIZE=20   
 VALUE="<%=TotalMilesParm%>"></TD> 
</TR> 
<TR> 
<TD WIDTH="5%"></TD> 
<TD COLSPAN="1" ALIGN="LEFT">Transaction id:</TD> 
<TD ALIGN="left"><INPUT TYPE="TEXT" NAME="transactionId"  
 SIZE=20 VALUE="<%=TransactionIdParm%>"></TD> 
</TR> 
<TR> 
<TD WIDTH="5%"></TD> 
<TD COLSPAN="1" ALIGN="LEFT"><INPUT TYPE="SUBMIT"  
 NAME="AddMiles" VALUE="Add Miles"></TD> 
<TD ALIGN="left"><INPUT TYPE="TEXT" NAME="addMiles"  
 SIZE=20 VALUE="0"></TD> 
</TR> 
<TR> 
<TD WIDTH="5%"></TD> 
<TD COLSPAN="1" ALIGN="LEFT"><INPUT TYPE="SUBMIT"  
 NAME="SubtractMiles" 
VALUE="Subtract Miles"></TD> 
<TD ALIGN="left"><INPUT TYPE="TEXT" NAME="subtractMiles"  
 SIZE=20 VALUE="0"></TD> 
</TR> 
<% 
   } 
%> 
</TABLE> 
<BR> 
<INPUT TYPE="SUBMIT" NAME="GetCustomer"  
 VALUE="Get Customer">

TotalMilesParm 为负数时从视图中隐藏的还有用户可以单击来添加和减去常旅客里程的按钮。因此只有从数据库中检索出有效的客户之后,用户才可以按这些按钮。每个 INPUT 字段都根据与此字段关联的 Parm 变量分配了值,除了 addMilessubtractMiles 始终设置为零。有理由假定用户在按 AddMilesSubtractMiles 按钮之前,他们都将会更改这些值。

从 Web 服务获取客户

每个按钮都是独立处理的。操作 Get Customer 按钮的处理的代码如下所示。这个代码块由查看 GetCustomerButton 变量是否为 null 开始。然后它把 customerId 输入字段中的信息转换到 CustomerIdParm 变量中:

if (GetCustomerButton != null)
   {
   CustomerIdParm = Integer.parseInt(request.getParameter("customerId"));
   %>
   <jsp:useBean id="GetCustomerByIdElement" scope="session" 
      class="com.justpc.GetCustomerByIdElement" />
   <%
   GetCustomerByIdElement.setCustomerName(CustomerNameParm);
   GetCustomerByIdElement.setCustomerId(CustomerIdParm);
   GetCustomerByIdElement.setTotalMiles(TotalMilesParm);
   com.justpc.GetCustomerByIdResponseElement mtemp = 
      AirlineMiles.GetCustomerById(GetCustomerByIdElement);
   
   if(mtemp != null)
      {
      CustomerNameParm = markup(String.valueOf(mtemp.getCustomerName()));
      TotalMilesParm = 
	     Integer.parseInt(markup(String.valueOf(mtemp.getTotalMiles())));
      }

   }

下一步,定义另一个 JavaBean 来保留将要传送到 GetCustomerById Web 方法的变量。客户名称、客户标识和总计里程的值被复制到 bean 中,而 bean 接着被传送到 GetCustomerById 方法。该方法返回一个称作 GetCustomerByIdResponseElement 的结构。它存储在 mtemp 变量中。如果 mtemp 不为 null,则抽取新的值赋给 CustomerNameParmTotalMilesParm。否则,保留它们的缺省值。

增加和扣除里程

用于响应单击 Get Customer 按钮的相同技术被用来确定何时处理 Add MilesSubtract Miles 按钮。因为两个按钮的处理代码几乎是相同的,只是变量名有所不同,所以在此只讨论 Add Miles 按钮。

这个代码块由测试 AddMilesButton 变量为 null 开始。如果它的值不为 null,则该按钮被按,而且应该调用 CreditMiles Web 方法来更新客户的常旅客里程:

if (AddMilesButton != null)
   {
   CustomerIdParm  = Integer.parseInt(request.getParameter("customerId"));
   AddMilesParm  = Integer.parseInt(request.getParameter("addMiles"));
   TransactionIdParm = 
      Integer.parseInt(request.getParameter("transactionId"));
   %>
   <jsp:useBean id="CreditMilesElement" scope="session" 
      class="com.justpc.CreditMilesElement" />
   <%
   CreditMilesElement.setMiles(AddMilesParm);
   CreditMilesElement.setCustomerId(CustomerIdParm);
   CreditMilesElement.setTransactionId(TransactionIdParm);
   CreditMilesElement.setAgency(AgencyParm);
   com.justpc.CreditMilesResponseElement mtemp = 
      AirlineMiles.CreditMiles(CreditMilesElement);

   if (mtemp != null)
      {
      TransactionIdParm = 
         Integer.parseInt(markup(String.valueOf(mtemp.getTransactionId())));
      }   
   
   }

与 Get Customer 按钮的逻辑一样,保留要传送至 Web 方法的信息的变量会被 Web 页面中对应的值更新。然后定义另一个 bean 来保留将要传送至 Web 方法的值。当 CreditMiles Web 方法被调用时,结果在另一个称作 mtemp 的结构中返回。如果 mtemp 不为 null,则从该结构中抽取新的 TransactionId 值并保存在 TransactionIdParm 中。

运行应用程序

通过在 J2EE Explorer 窗格中右键单击 JSP 文件的名称并从上下文菜单选择 Run on Server,您可以直接在 WebSphere 中测试应用程序。将会显示一个新的带有 Web 浏览器的选项卡。在该浏览器中,您将看到 JSP 应用程序。在 Customer id 字段中输入有效的值并单击 Get Customer 按钮之后,您将看到如下所示的结果:

结束语和参考资料

结束语

在本教程中,您看到了如何创建 JavaServer Page,它调用 Visual Basic .NET Web 服务,并接着访问 DB2 数据库。所有的 DB2 工作(包括构建表和编写存储过程)都是使用 Microsoft Visual Studio .NET 和 IBM DB2 Development Add-in 来完成的。DB2 Development Add-in 也包含一些工具,它们使在开发过程中检查数据库表的内容和测试存储过程变得很简便。

注册的 Visual Basic .NET Web 服务使用 DB2 管理的提供程序来访问 DB2 数据库。DB2 管理的提供程序是与标准的 System.Data 类兼容的,而且如果您已经对 SQL Server 管理的提供程序很熟悉,那么换作 DB2 几乎是易如反掌的。

构建 JavaServer Page 会涉及创建 Web 服务客户机代理(包含在 JavaBean 中)。一旦创建了 JavaBean,就可以轻而易举地编写少许 Java 代码以及一些 HTML 标记来创建最终的 Web 应用程序。

参考资料


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Information Management
ArticleID=85536
ArticleTitle=用 DB2、Visual Basic .NET 和 Java 构建 Web 服务
publish-date=10192010