在Oracle10g上构建PL/SQLWeb服务

发表于:2007-05-25来源:作者:点击数: 标签:oracleSQLWebOracle10g构建服务
Oracle Database 10g web 服务允许您在数据库内部使用外部 web 服务时,利用您在 PL/SQL 和 SQL 中的 开发 投入。下面叙述如何构建您自己的 web 服务。 正如现在我们都了解的那样,web 服务模型已证明是连接应用程序的一种有效的方式。Web 服务协议,如 XML

  Oracle Database 10g web 服务允许您在数据库内部使用外部 web 服务时,利用您在 PL/SQLSQL 中的开发投入。下面叙述如何构建您自己的 web 服务。
  
  正如现在我们都了解的那样,web 服务模型已证明是连接应用程序的一种有效的方式。Web 服务协议,如 XML — 用于信息交换的事实标准、SOAP (简单对象访问协议) — 使您能够在分布式环境中通过 HTTP、FTP、SMTP来交换 XML 文档、WSDL (Web 服务描述语言)和 UDDI,都允许您构建平台和语言独立的、松散耦合的分布式应用程序。
  
  您可以在 Oracle Database 10g 和 Oracle Application Server (OracleAS) 10g 中(通过内置在 OracleAS 中的 OC4J 版本)提供和使用 web 服务。Oracle Database 10g 允许您使用 PL/SQL (程序包、过程、函数和触发器)、SQL 查询、SQL DML 语句和 Java 存储过程来定义 Web 服务的功能,OracleAS web 服务允许您用 J2EE (企业 JavaBeans、JMS 等)来定义 Web 服务的功能。您还可以利用 OracleAS 将数据库功能作为 J2EE web 服务提供。
  
  不过,本文仅重点叙述 PL/SQL 数据库 web 服务。根据定义,Oracle Database 10g web 服务在数据库中提供功能;它们允许您利用您在 PL/SQL 和 SQL 中的开发投资,同时从数据库内部使用外部的 web 服务。
  
  在本文中,我将向您介绍数据库 web 服务,以及如何为 Oracle Database 10g 创建、发布和调用 PL/SQL web 服务。本文中引用的所有脚本和文件都在这里提供。
  
  所需软件
  在您跟随本文中给出的示例之前,您将需要安装以下软件:
  
  Oracle Components for J2EE (OC4J) 9.0.3 版或更高版本;您将需要独立完整版(也称为扩展版)
  Oracle Database 10g
  Oracle Net 10g
  Oracle SQL*Plus (和客户端或企业安装软件一起包含)
  Java 软件开发人员工具包 (SDK) 1.4 版或更高版本
  
  数据库模式设置
  首先,我们需要设置我们的数据库模式,一个简化的 web 商店示例。
  
  在发布您稍后将看到的 web 服务之前,您必须首先按如下方式创建一个名称为 store 的用户,并将授予该用户以下所需权限(您必须首先作为拥有 CREATE USER 权限的用户登录到数据库,以创建用户):
  
  CREATE USER store IDENTIFIED BY store;
  GRANT connect, resource TO store;
  
  注意:您将在文件 web_services.sql 中找到这些语句和这一部分中出现的设置商店模式的其它语句。
  
  接下来的两条语句作为 store 用户进行连接,并创建一个名称为 order_sq 的序列,该序列稍后用来填充订单表的主键:
  
  CONNECT store/store;
  CREATE SEQUENCE order_sq;
  
  下面的语句创建所需的四个数据库表,名称分别为:product_types、products、customers 和 orders:
  
  CREATE TABLE product_types (
   product_type_id INTEGER
    CONSTRAINT product_types_pk PRIMARY KEY,
   name VARCHAR2(10) NOT NULL
  );
  
  CREATE TABLE products (
   product_id INTEGER
    CONSTRAINT products_pk PRIMARY KEY,
   product_type_id INTEGER
    CONSTRAINT products_fk_product_types
    REFERENCES product_types(product_type_id),
   name VARCHAR2(30) NOT NULL,
   description VARCHAR2(50),
   price NUMBER(5, 2)
  );
  
  CREATE TABLE customers (
   customer_id INTEGER
    CONSTRAINT customers_pk PRIMARY KEY,
   first_name VARCHAR2(10) NOT NULL,
   last_name VARCHAR2(10) NOT NULL,
   dob DATE,
   phone VARCHAR2(12)
  );
  
  CREATE TABLE orders (
   order_id INTEGER
    CONSTRAINT orders_pk PRIMARY KEY,
   product_id INTEGER
    CONSTRAINT purchases_fk_products
    REFERENCES products(product_id),
   customer_id INTEGER
    CONSTRAINT purchases_fk_customers
    REFERENCES customers(customer_id),
   quantity INTEGER NOT NULL
  );
  
  注意:如果您在一个不同的模式中为 store 用户创建了这些数据库表,那么您将需要修改示例配置文件中的模式名称(您稍后将看到这些示例配置文件)。
  
  product_types 表用来存储示例在线商店可能存有的产品类型的名称,products 表包含关于销售的商品的详细信息,customers 表存储关于获许从商店订购产品的客户的信息,orders 表包含哪一个客户订购了产品的详细信息。
  
  下面的 INSERT 语句添加行到 customers、product_types 和 products 表中:
  
  INSERT INTO customers (
   customer_id, first_name, last_name, dob, phone
  ) VALUES (
   1, 'John', 'Brown', '01-JAN-1965', '800-555-1211'
  );
  
  INSERT INTO product_types (
   product_type_id, name
  ) VALUES (
   1, 'Book'
  );
  
  INSERT INTO products (
   product_id, product_type_id, name, description, price
  ) VALUES (
   1, 1, 'Modern Science', 'A description of modern science', 19.95
  );
  
  COMMIT;
  
  我们将使用 PL/SQL 来实施我们的数据库 web 服务代码。在您将 PL/SQL 代码作为 web 服务发布之前,您必须把它放在一个程序包中。列表 1 中的语句创建了一个 PL/SQL 程序包,这个程序包包含一个允许客户订购某种产品的过程。这个程序包的名称为 dbfunc,它包含一个名称为 place_order() 的过程,该过程接收产品的 ID、客户的 ID 和要购买的产品的数量。
  
  您许可以看到,place_order() 函数检查在 products 和 customers 表中是否存在产品 ID 和客户 ID,如果存在,则在 orders 表中添加一行,从而返回一个包含该订单 ID (这是由 order_sq 序列生成的值)的字符串。如果客户 ID 或产品 ID 无效,则返回一个包含错误消息 "No such customer" 或 "No such product" 的字符串。
  
  现在,让我们看看如何安装和配置 OC4J。
  
  安装和配置 OC4J
  您必须用以下示例命令来安装 OC4J (当准备这篇文章时,我使用了 Windows 2000 命令提示工具,您可以使用 Unix 或 Linux shell 中的类似的命令工具,方法是在目录路径中用斜杠 (/) 来替换反斜杠 (\)):
  
  e:
  cd e:\oracle\oc4j\j2ee\home
  java -jar oc4j.jar -install
  
  然后将会提示您输入管理用户的口令。我用 welcome 作为我的口令。
  
  您需要在 data-sources.xml 文件(该文件位于 oc4j\j2ee\home\config 目录中)中定义一个数据源,方法是添加类似于以下数据源元素的一部分内容:
  
  注意:您可以在 OTN 网站上找到本文的示例 data-sources.xml 文件。您可能需要修改 Oracle 数据库服务的名称 — 我使用默认的 ORCL 服务标识符 (SID) 并本地运行,Oracle Net 监听端口 1521,以进行连接。如果您的数据库在一个不同的服务器上运行,并有一个不同的端口号,或一个不同的 SID,那么您将需要相应地修改数据源元素。您的数据库管理员能够为您提供数据库的相应的连接详情。此外,如果您在一个不同的模式中创建了示例数据库表,那么您将需要在 data-sources.xml 文件中修改您的设置中的用户名和口令。
  
  接下来,您需要通过以下命令启动 OC4J:
  e:
  cd e:\oracle\oc4j\j2ee\home
  java -jar oc4j.jar
  
  您将看到一条指示 OC4J 已经启动的确认消息。
  
  将 PL/SQL 程序包作为数据库 Web 服务发布
  
  接下来,让我们看看如何将 dbfunc PL/SQL 程序包作为 web 服务发布。
  
  实质上,数据库 web 服务使用 OC4J 中的功能来提供 Java 类 — Java 类在数据库中充当您的 web 服务的实际实施的一个包装。您的实施可以用 SQL 或 Java 存储过程以及 PL/SQL 来编写。
  
  您可以使用 OC4J 9.0.3 版或更高版本自带的 web 服务汇编工具来发布 PL/SQL 程序包。您需要将一个 config.xml 文件传递给 web 服务汇编工具,config.xml 包含关于数据库模式中您想要将它作为 web 服务提供的 PL/SQL 程序包的信息。列表 2 包含了我们的示例中使用的示例 config.xml 文件。(您还可以使用 JDeveloper 来发布 web 服务,但那是另外一篇文章:“轻松进行 Web 服务开发”(作者:Elangovan Balusamy)要叙述的内容。)
  
  如果您的数据库在一个不同的服务器上运行、拥有一个不同端口号、或拥有一个不同于 localhost、1521 和 ORCL 的 SID,那么您将需要修改 db-url 元素中的项目。httpServerURL 项目拥有默认的服务器和端口号, OC4J 在其上作为 localhost 运行在端口 8888 上。如果您的 OC4J 运行在一个不同的服务器和端口上,那么您将需要编辑 config.xml 文件。(注意:您可以在您安装 OC4J 的 j2ee\home\config 目录下的 http-web-site.xml 文件中找到服务器和端口设置。此外,如果您在一个不同的模式中创建了示例数据库表,那么您将需要修改 config.xml 文件中的设置中的模式。)
  
  要将 dbfunc 作为 web 服务发布,您可以运行以下命令:
  
  set ORACLE_HOME=E:\oracle\oc4j
  
  set CLASSPATH=.;%ORACLE_HOME%\webservices\lib\wsdl.jar;%ORACLE_HOME%
   \lib\xmlparserv2.jar;%ORACLE_HOME%\soap\lib\soap.jar
  
  java -jar %ORACLE_HOME%\webservices\lib\WebServicesAssembler.jar -config
   G:\OTN_articles\dws\config.xml
  
  java -jar %ORACLE_HOME%\j2ee\home\admin.jar
   ormi://localhost admin welcome -deploy -file ./dbfunc.ear -deploymentName dbfunc
  
  java -jar %ORACLE_HOME%\j2ee\home\admin.jar
   ormi://localhost admin welcome -bindWebApp dbfunc dbfunc_web http-web-site /plsqlsample
  
  前两条命令设置所需的环境变量(名称为 ORACLE_HOME 和 CLASSPATH)。您将需要把 ORACLE_HOME 的设置改为您安装 OC4J 的完整独立版的目录。CLASSPATH 变量包含部署 web 服务所需的 JAR 文件的位置。第三条命令利用 config.xml 文件来使用 WebServicesAssembler JAR 文件发布 web 服务。(您将需要把 -config 选项中的目录改为您存储 config.xml 文件的位置。)第四条命令部署 web 服务,部署名称为 "dbfunc"。(如果您的 OC4J 管理帐户使用了一个不同于 "welcome" 的口令,您将需要相应地设置它。)第五条命令通过路径 /plsqlsample 将 dbfunc web 服务连接到名称为 http-web-site的默认 web 站点上。(注意:如果您正部署到内置于 Oracle 9iAS 中的 OC4J,那么在第四条命令中,您将需要用 default-web-site 来替换 http-web-site。
  
  您已经成功地发布了您的 web 服务,现在该调用它了。接下来让我们进行这一操作。
  
  调用数据库 Web 服务
  您可以用一个 web 浏览器来调用 web 服务。要实现这一目的,请将浏览器指向以下位置:
  
  http://localhost:8888/plsqlsample/dbfunc
  
  (注意:如果您的 OC4J 在一个不同于 localhost 的服务器、8888 的端口上运行,那么您将需要用您相应的设置来替换它们。此外,如果您正部署到内置于 Oracle 9iAS 的 OC4J,那么您将需要在配置文件中获取端口设置。)
  
  图 1 显示了在我的计算机上显示的 web 页面。
  
 

  
图" 1

  如果您单击服务描述链接,您将看到包含该 web 服务的 WSDL 描述的 XML。(参见列表 3)
  
  您可以看到,列表 3 包含 web 服务的 WSDL 描述。WSDL 中的下面这些行显示输入参数和一个输出参数:
  
  - <message name="placeOrderInput">
   <part name="param0" type="xsd:decimal" />
   <part name="param1" type="xsd:decimal" />
   <part name="param2" type="xsd:decimal" />
   </message>
  - <message name="placeOrderOutput">
   <part name="output" type="xsd:string" />
   </message>
  
  三个输入参数是将要传递给 place_order() PL/SQL 函数的数字,这三个数字分别是产品 ID、客户 ID 和数量。输出参数是由 place_order() 函数返回的字符串,该字符串包含了指示下单是否成功的消息。
  
  返回到图 1 中显示的 web 页面,单击浏览器中的 placeOrder 链接。下一个 web 页面显示如图 2,继续进行,在 placeOrder() 函数中输入三个所需的数字参数(如在图 2 中显示的那样):我分别为产品 ID、客户 ID 和数量输入了 1、1 和 2。
  
 

  
图" 2

  接下来,您应当单击 Invoke 按钮来实际运行 web 服务。运行通过 SOAP 来完成。在 web 服务启动和运行后,经过一个短延时,您将在浏览器中看到作为结果产生的输出,输出的一个示例在图 3 中显示。
  
 

  
图" 3

  从图 3 中,您可以看到来自 web 服务的 SOAP 消息被显示在浏览器中,并且在 xsd:string 部分中来自 place_order() 函数的输出字符串被设为 "Order placed with ID of 1"。数值 1 来自数据库中的 order_sq 序列。注意:如果您多次调用 web 服务,您将看到这个值每次加 1。
  
  在数据库内部,place_order() 函数在 orders 表中插入一行。使用 SQL*Plus 作为 store 用户登录到数据库中并运行以下 SELECT 语句,您可以看到这一行:
  
  SQL> SELECT * FROM orders WHERE order_id = 1;
  
   ORDER_ID PRODUCT_ID CUSTOMER_ID  QUANTITY
  ---------- ---------- ----------- ----------
       1     1      1     2
  注意,该行的各个列值被设为预期值。
  
  如果您试图使用该 web 服务对一种不存在的产品下单(例如,ID 为 3 的产品),您将看到在图 4 中显示的输出。
  

  
图" 4

  从图 4 中,您可以看到从 place_order() 函数返回的字符串为 "No such product"。如果您试图为一个不存在的客户下单,那么您将看到返回的字符串为 "No such customer"。在这两种情况下都不插入行到 orders 表中,因为订单是无效的。
  
  您还可以从数据库内部使用 web 服务。这种方法允许数据库执行诸如跟踪、聚合和刷新由远程 web 服务生成的数据之类的任务。您可以通过 SOAP 来使用 web 服务,并使用 Oracle Java 虚拟机或 PL/SQL 来调用远程 web 服务。您可以从数据库中将参数传递给 web 服务,并定义一个虚拟数据库表,您可以用这个表来访问由 web 服务返回的数据。

原文转自:http://www.ltesting.net