从 Java 存储过程调用
外部 Web 服务
目录
该示例演示了如何从 Oracle9i
数据库内部调用 Web 服务。本演示实现的方案是一个简单的采购模块。将向用户显示一个产品目录。用户可以浏览产品目录并采购感兴趣的产品。根据用户提供的登录信息对用户进行身份验证,稍后提供订单。
该示例使用一个信贷机构 Web 服务,该服务维护一个关于客户及其信用卡信息的信息中心库。该服务提供两个方法:一个方法向客户授权,
另一个方法向客户信用卡账户开具采购的帐单。
用户开始采购后,会发生以下顺序的事件:
- 用户应该先提供一个客户 id,然后才能下单。
- 信贷机构 Web 服务对该客户授权。
- 如果客户 id 无效,则该 Web 服务返回“INVALID_CUSTOMER”。
在这种情况下,向客户显示适当的消息。
- 然而,如果客户 id 有效,则该 Web 服务返回“VALID_CUSTOMER”。然后,将订单信息添加到数据库中。订单状态将存储为“PENDING”。
- 购物中心的发货营业员查看未决的订单,选择要交付的订单。发货营业员还根据库存中特定产品的可用数量来修改要发货的商品数量。该操作对数据库启动一个更新操作,将
订单的状态修改为“IN_SHIPPING”。
- 自动处理并配置该交付过程以使其每 6 分钟运行一次(用于演示目的)。该过程扫描数据库以获取准备交付的订单(状态为 IN_SHIPPING 的订单)。
- 交付的第一步是向客户的帐户开帐单。这由信贷机构 Web 服务处理,调用该服务时要提供客户信息和购物金额。
- 该 Web 服务处理传送给它的信息。
- 如果客户帐户中的金额充足,则从该帐户收费并返回一条成功消息。
- 如果客户帐户中的金额不足,则该 Web 服务返回一个字符串“INSUFFICIENT_FUNDS”,客户帐户恢复到原有金额。
- 如果该 Web 服务没有承认该客户,则返回一个故障字符串为“INVALID_CUSTOMER”的故障。
- 数据库进程根据 Web 服务的响应更新订单表。如果支付成功,订单状态就会从“IN_SHIPPING”更改为“SHIPPED”。如果客户帐户没有足够的资金,则订单状态变为“INSUFFICIENT_FUNDS”。
这标记着此特定订单生命周期的结束。用户可以随时查看订单的状态。而且,发货人员干预要交付的数量是为了视觉效果目的而提供的,整个过程可能已经自动化,无需人工干预,使用的是与处理交付过程相同的存储过程。
图 1.1 说明了该示例应用程序的架构。
最终用户浏览产品目录并下单。用户提供的信息首先由信贷机构 Web 服务验证,然后添加到数据库中。购物中心的发货营业员定期查看未决的订单。Java Server Page 处理该请求 ,然后查找数据库并显示未决的订单。发货营业员选择要向客户交付的订单,然后根据库存中可用的数量来确定要交付的产品数量。该操作将订单状态更新为“IN_SHIPPING”。一个 PL/SQL 作业在数据库中运行,
配置为每 6 分钟运行一次(用于演示目的)。该作业执行一个 java 存储过程以从客户帐户收取费用,商场发货营业员已经批准该客户的订单。客户 id 和购物款额传递至该存储函数。该存储函数对所有必需的信息进行打包,然后与信贷机构 Web 服务进行通讯。Web 服务从客户信用卡帐户收取购物款额,并根据付费操作返回一个响应。存储函数根据 Web 服务返回的值更新订单表。
Java 存储过程是用来桥接 SQL、Java、J2EE、XML 和 Web 服务的强大机制;有关详细信息,请参阅白皮书 — 发挥 Java 存储过程的威力
图 1.1 — 应用程序体系结构图

通过图 1.2 中所示的产品目录屏幕,用户可以浏览商店中提供的各种产品。用户可以选择任何产品并输入所需的数量。如果没有输入数量,则默认为一个。用户可以指定他们的客户 ID,然后单击 Place Order 按钮来启动
采购。
图1.2 —产品目录屏幕
采购结果如图 1.3 所示。Web 服务成功验证用户后,会显示该屏幕。
图 1.3 — 采购结果屏幕
采购结果如图 1.4 所示。如果用户输入了无效的用户 id,则显示该屏幕。Web 服务无法识别客户,因此返回一个故障字符串。
图 1.4 — 采购结果屏幕
订单列表屏幕如图 1.5 所示。通过该屏幕,发货营业员可以浏览商店中下的各个订单。发货营业员选择任何要交付的订单,单击 Ship Order 按钮,启动支付和发货过程。
图 1.5 — 订单列表屏幕
图 1.6 显示对发货营业员所请求的交付的响应屏幕。它显示了订单、客户以及订单的状态。
图 1.6 — 交付响应屏幕
用户可以使用下面显示的屏幕查看任何订单的状态。用户需要输入将在图 1.3 中显示的订单 ID。
图 1.7 — 查看订单状态屏幕
用户在图 1.7 中输入一个有效的订单 id 并单击 Get Order Details 后,
该特定订单的状态如下所示。
图 1.8 — 查看订单状态响应屏幕
- Oracle9i 数据库 9.0.1 版或更高版本。可以从 Oracle 技术网下载 Oracle9i 数据库。
- Oracle9iAS Containers for J2EE (OC4J) 9.0.2 或更高版本(可从此处获得)以及 JDK 1.2 或更高版本(可从此处获得)
或 Oracle9i JDeveloper 版本 9.0.3.988 预览或更高版本(可从此处获得)
- 如果希望把应用程序部署到独立的 OC4J,那么必须下载并安装 Jakarta Ant 实用程序 1.4 版
本部分为成功运行该应用程序提供了逐步指导。 本部分采用以下几个子部分进行讨论
符号
解压缩应用程序的源代码
配置应用程序
部署应用程序
运行应用程序
- %SAMPLE_HOME% — 将 WSClientSample.jar 文件解压缩到该目录。
- %OC4J_HOME% - 用来安装 OC4J 的目录。例如,如果将 oc4j_extended.zip 解压缩到了 C:\OC4J,则 %OC4J_HOME% 将是 C:\OC4J。
- %ORACLE_HOME% — 用于安装 Oracle9i 客户端或数据库软件的目录。
- %ANT_HOME% - 用来在其中解压缩 Ant 分发的目录。
应用程序文件存储在名为 WSClientSample.jar 的档案文件中。下载该档案文件,并将其解压缩到方便的目录 (%SAMPLE_HOME%) 中。执行以下命令,解压缩文件:
jar xvf WSClientSample.jar
档案文件 WSClientSample.jar 解压缩将数据库作为 Web 服务客户端演示实施的文件。所有文件都解压缩到 WSClientSample 目录种。该目录具有随后描述的所有资源。
1. 该演示需要在数据库中创建一些数据库表和序列。目录 %SAMPLE_HOME%/WSClientSample/config 中的 WSCreate.sql 文件为创建所需数据库对象并以示例数据置入该对象提供了脚本。
编辑该文件,指定应用服务器主机和端口号。您需要修改以下行:
execute dbms_java.grant_permission('WS','SYS:java.net.SocketPermission','<server-host-name>:<port>','connect,resolve');
例如,
execute dbms_java.grant_permission('WS','SYS:java.net.SocketPermission','incq184b.idc.oracle.com:8888','connect,resolve');
2. 您需要执行 WSCreate.sql 脚本。以任意用户的身份连接到数据库,并在 SQL 提示符下运行以下命令:
SQL>@%SAMPLE_HOME%/WSClientSample/config/WSCreate.sql
这将创建新用户“WS”(口令为 WS),它具有所有必要的表和权限。
3. 确保 %ORACLE_HOME%\bin 在系统路径中。该演示需要向数据库中载入一些 jar 文件。这是在命令提示符处实现的,如下所示:
loadjava -thin -user sys/<sys-password>@<hostname>:<port>:<SID> -resolve -synonym -verbose -grant public %OC4J_HOME%/soap/lib/soap.jar %OC4J_HOME%/lib/dms.jar %OC4J_HOME%/jlib/javax-ssl-1_1.jar %ORACLE_HOME%/lib/servlet.jar %OC4J_HOME%/jdk/jre/lib/ext/mail.jar
例如,
loadjava -thin -user sys/change_on_install@insn104a.idc.oracle.com:1521:otn9i -resolve -synonym -verbose -grant public c:\soap\lib\soap.jar c:\lib\dms.jar c:\jlib\javax-ssl-1_1.jar c:\orahome\lib\servlet.jar c:\jdk\jre\lib\ext\mail.jar
这将加载 sys 模式中所有必需的类并为它们创建公共同义词。
注意:这一步可能需要一段时间才能完成。
4. 编辑 %SAMPLE_HOME%/WSClientSample/src/oracle/otnsamples/wsclient 目录中的 CreditAgencyServiceStub.java 文件。您需要用步骤 1 中指定的值更改 Web 服务端点。编辑下面几行:
/* * Change this variable to point to your web service end-point
*/ public String endpoint = "http://<server-host-name>:<port>/wsclient/CreditAgencyService";
例如,
public String endpoint = "http://incq184b.idc.oracle.com:8888/wsclient/CreditAgencyService";
5. 确保 %ORACLE_HOME%\bin 在系统路径中。该演示要求将 Web 服务客户端和存根加载到数据库中。这是在命令提示符处实现的,如下所示:
loadjava -thin -user ws/ws@<hostname>:<port>:<SID> -resolve -verbose %SAMPLE_HOME%/WSClientSample/src/oracle/otnsamples/wsclient/CreditAgencyServiceStub.java %SAMPLE_HOME%/WSClientSample/src/oracle/otnsamples/wsclient/CreditAgencyServiceClient.java
其中:
hostname |
安装数据库的主机名称 |
port |
数据库的 TNS 监听器端口 |
SID |
数据库名称 |
例如,
loadjava -thin -user ws/ws@insn104a.idc.oracle.com:1521:otn9idb c:\WSClientSample\src\oracle\otnsamples\wsclient\CreditAgencyServiceStub.java c:\WSClientSample\src\oracle\otnsamples\wsclient\CreditAgencyServiceClient.java
6. 需要发布前一步骤中加载的 Web 服务客户端,因此必须创建一个数据库作业来调用该 Web 服务。这是通过 WSProcedure.sql 完成的
以任何用户身份连接到数据库,并在 SQL 提示符下运行 WSProcedure.sql 脚本: SQL>@%SAMPLE_HOME%/WSClientSample/config/WSProcedure.sql
该 sql 脚本将在前一步骤中创建的存储过程发布到数据库,并创建一个每 6 分钟调用 CreditAgencyServiceClient.java 的作业。
7. 编辑 %SAMPLE_HOME%/WSClientSample/config 目录中的 Connection.properties 文件。将 hostname、SID 和 Port 更改为要连接到的数据库实例的那些设置。
更改以下行:
| HostName |
= |
insn104a.idc.oracle.com |
| SID |
= |
otn9i |
| Port |
= |
1521 |
| UserName |
= |
oe |
| Password |
= |
oe |
采用以下方式之一可将该应用程序部署到 OC4J 实例
将应用程序部署到 Oracle9i JDeveloper 的
嵌入 OC4J
EAR(企业应用程序归档)部署
将应用程序部署到 Oracle9i Jdeveloper 的嵌入 OC4J
1. 打开 Oracle9i JDeveloper。
2. 导航到 %SAMPLE_HOME%/WSClientSample
3. 打开 WSClientSample.jws 文件并单击 WSClientSample.jws 节点将其展开。
4. 单击 WSClientSample.jpr 节点将其展开。
5. 只需单击 Run 菜单上的 Run WSClientSample.jpr,即可从 JDeveloper 运行应用程序。
1. 确保 %ANT_HOME%\bin 在系统路径中。还要让 OC4J_HOME 环境变量指向 %OC4J_HOME%。使用以下命令从 %SAMPLE_HOME%/WSClientSample 生成 EAR 文件 —
ant -buildfile build.xml
2. 启动 OC4J。[ java -jar oc4j.jar from %OC4J_HOME%/j2ee/home]
3. 使用以下内容从 %OC4J_HOME%\j2ee\home 部署 EAR
java -jar admin.jar ormi://<host>:<port> <uid> <password> -deploy -file %SAMPLE_HOME%/WSClientSample/WSClientDemo.ear -deploymentName wsclient 这将用“wsclient”名称部署应用程序
现在,使用以下命令将该 Web 应用程序绑定到网站,
java -jar admin.jar ormi://<host>:<port> <uid> <password> -bindWebApp wsclient WSClientDemo http-web-site /wsclient 其中,
| http-web-site |
:绑定 Web 应用程序的网站 |
| host |
该站点的主机/IP |
| port |
该站点的端口 |
| uid |
:admin 用户 id |
| password |
:admin 口令 |
4. 这样就完成了到独立 OC4J 服务器的部署。您可以按照运行应用程序中给出的步骤访问应用程序。
注意:若要取消部署该应用程序,可使用 java -jar admin.jar ormi://localhost:<port> <uid> <password> -undeploy wsclient
1. 打开浏览器并键入 URL,以访问该应用程序。URL 应为以下类型
http://<server_host_name>:<port>/wsclient/Products.jsp 其中,<server_host_name>:应用服务器的 URL。例如,incq184b.idc.oracle.com <port>:该服务器所使用的端口号。缺省值为 8888。
2. 可以选择购买任何产品。
3. 针对客户 ID,您可以指定 otn-user 或 oracle-user。
4. 成功下单并显示一条成功消息。
5. 要查看未决订单列表,请将 URL 更改为
http://<server_host_name>:<port>/wsclient/ShipOrders.jsp
6. 该操作将列出所有未决的订单。选择任何要交付的订单。如果任何请求的产品的数量超过库存中的现有数量,则修改所请求的数量。这会将订单状态更新为“IN_SHIPPING”
7. 下次运行批作业时,根据购物款额以及客户的信用余额更新该订单状态。如果您想了解作业下次执行的时间,则以 ws/ws 身份连接到数据库。在 SQL 提示符下执行以下查询:
SQL> SELECT last_date, last_sec, next_date, next_sec FROM user_jobs WHERE what LIKE 'ws_client%';
该操作将列出有关作业上次执行时间以及下次执行日期和时间的详细信息。
8. 作业执行完毕之后,您还可以查询订单状态以查看 Web 服务的响应。为此,单击主页标题中提供的 View Order Status 链接,或者打开一个浏览器并键入以下 URL —
http://<server_host_name>:<port>/wsclient/ViewOrders.jsp
|
目录 |
文件名 |
说明 |
|
WSClientSample |
build.xml |
使用 ANT 生成部署文件的项目构建文件
|
WSClientSample.jws |
Oracle9i JDeveloper 工作区文件 |
WSClientSample.jpr |
Oracle9i JDeveloper 项目文件 |
WSClientSample/config |
application.xml |
用于应用服务器的配置文件 |
WSCreate.sql |
该 sql 脚本用于创建数据库用户和示例应用程序所需的所有表 |
WSProcedure.sql |
该 sql 脚本用于将 Java 存储过程发布到数据库并创建用于调用 Java 存储过程的 PL/SQL 批处理作业 |
Connection.properties |
该文件包含数据库连接参数的详细信息 |
WSClientSample/doc |
Readme.html |
本文件 |
WSClientSample/doc/images |
GIF Files |
本自述文件中使用的图像文件 |
WSClientSample/src/oracle/otnsamples/wsservices |
CreditAgencyService.java |
该类实现了一个
简单的无状态会话 Java Web 服务。它提供两个基本功能 — 对客户授权,以及向客户的信用卡帐户开帐单 |
ICreditAgencyService.java |
该 Web 服务接口列出作为 Web 服务公开的方法。 |
CreditAgencyService.wsdl |
Web 服务的 XML 描述 |
ConnectionManager.java |
Java Bean 用于管理 Web 服务的数据库连接 |
WSClientSample/src/oracle/otnsamples/wsclient |
CreditAgencyServiceClient.java |
该 Java 存储过程调用信贷机构 Web 服务来验证用户 |
CreditAgencyServiceStub.java |
用于 Credit Bureau Web 服务的客户端存根。这是一个代表远程服务的本地对象。这是从 Oracle9i JDeveloper 生成的 |
StoresBean.java |
Java Bean 用于 Java Server Page,并处理所有数据库操作 |
ProductsInfo.java |
用于在 Java Server Page 和 Java Bean 之间传递产品信息的值对象 |
OrdersInfo.java |
用于在 Java Server Page 和 Java Bean 之间传递订单信息的值对象 |
WSClientSample/webroot |
Products.jsp |
检索数据库中的产品信息并向用户显示目录。当用户下发购买产品的请求时,调用 ProductsBean 将订单添加到数据库 |
ViewOrders.jsp |
检索特定订单 ID 的订单状态 |
ShipOrders.jsp |
从数据库中为发货营业员检索订单信息。当发货营业员选择要交付的订单时,调用 ProductsBean 修改订单状态
|
ErrorHandler.jsp |
用于 Java Servre Page 的错误页 |
WSClientSample/webroot/web-inf |
web.xml |
用于 Web 容器的配置文件 |
修订记录: 2002 年 10 月 22 日
请将对此示例的意见发布在 OTN 示例代码论坛中。
|