级别: 初级 Masahiro Ohkawa (MOHKAWA@jp.ibm.com), 软件工程师, IBM Japan
2004 年 1 月 01 日 企业信息系统(EIS)能够向用户提供强大的功能。然而,它们的原始接口常常不够友好,提供和要求的数据常常与特定用户的需求不相关。在本文中,Masahiro Ohkawa 向您展示如何使用 WebSphere Application Developer Enterprise Edition 来创建一个门面接口(Facade interface),这个接口的作用是充当企业服务和外部世界的中间人。他用一个具体的示例来展示 Web 服务隐藏复杂性和获取用户所需信息的能力--仅此而已。
引言
企业服务允许通过 J2EE 连接器体系结构(J2EE
Connector Architecture,J2C)来访问企业信息系统
(EIS),比如 IBM IMS 和 CICS 产品。(您可以在 WebSphere Studio
Application Developer Enterprise Edition的帮助文档中找到更多关于企业服务的信息。在
WebSphere Studio --> Business integration --> Building enterprise services --> Concepts 中选择“Process of building an enterprise service”。
查阅下面的
参考资料部分可以获得关于 IMS、CICS 和 J2C 更多的信息。)
这种服务可以使用 WebSphere Studio Application Developer
Integration Edition 5 来构建。企业服务可以作为 Web 服务、会话 EJB(Enterprise JavaBean)组件、或消息驱动
Bean 提供给客户。但是每个企业服务接口仅代表它相应的企业信息系统(EIS)的接口。您可能想要向您的企业服务添加某些逻辑以便来增加值、集成多种企业信息系统(EIS)、或集成其他的 Java 组件。您可能也希望每个接口表示一个
工作单元
——即事务的执行或一组彼此相关的活动,这些活动必须同时完成或同时未完成。某些工作单元可能涉及一个企业信息系统(EIS)或多个企业信息系统中的多个应用程序。
在本文中,您将学习企业服务并且找到一种方法,通过提供一个称为门面
JavaBean(Facade JavaBean)的组件来添加某些逻辑。这个组件能够与多种企业服务和其他的 Java
组件交互。您也将看到一个更详细地阐明这个概念的简单示例:一个 Web
服务,它访问通过 IMS 打包的样本电话本(PhoneBook)应用程序。
什么是企业服务?
企业服务基于
面向服务的体系结构(SOA)。企业服务的定义是用 WSDL
文件编写的。您可以自己创建 WSDL 文件,也可以从 WSDL
文件生成您的服务的骨架,然后在这个骨架中编写应用程序代码;这称为
自顶向下开发。
另外,您也可以从现有的资源生成 WSDL 文件,然后从 WSDL
文件生成部署代码;这称为
自底向上开发。
您还可以通过创建
流程(process)
来创建与其他企业服务组合在一起的企业服务。(要了解更多关于流程的信息,可以查阅
WebSphere Studio Application Developer Integration Edition
的文档中的两个文档:“What is a process”(位于
WebSphere Studio --> Business integration --> Building processes -->
Concepts)以及“Travel Agency scenario”(位于
WebSphere Studio --> Business integration -->
Scenarios)。您也可以参考 IBM 的红皮书“Exploring WebSphere Studio Application Developer Integration Edition 5.0”(请参见
参考资料以获得它的链接)。
在本文中,我将使用自底向上开发来构建一个样本应用程序。构建访问企业信息系统(EIS)的企业服务的第一步如下所示:
- 创建一个服务项目。
- 通过定义相关的企业信息系统(EIS)连接信息来创建企业服务定义。
- 通过导入访问信息系统(EIS)的接口定义文件来更新企业服务定义。
在完成这些步骤之后,您将生成如下 WSDL 文件:
-
一个接口 WSDL 文件。它描述了服务的接口,包括数据类型和数据结构。
-
一个绑定 WSDL 文件。它描述了服务接口是如何实现的。
-
一个服务 WSDL 文件。它描述了 EIS 连接信息以及
JNDI 查找名称。在非受管环境中,使用 EIS 连接信息,但是不使用 JNDI
查找名称。在非受管环境中,使用 JNDI 查找名称,而不使用 EIS 连接信息;您将使用 JNDI 查找名称来查找在 Web
应用程序服务器中配置的 J2C 连接工厂。
下一步是产生企业服务的实现。企业服务可以作为 Web 服务、会话 EJB 组件、或者消息驱动的 bean
提供给客户。可以从企业服务定义中生成这些实现中的任何一个。服务代理 JavaBean
组件也可以从这个定义中生成。
企业服务定义同样也可以从 JavaBean
组件中生成。所以,JavaBean
组件可以通过转变成企业服务而配置成 Web 服务、会话 EJB 组件等等。
为企业服务提供门面接口
图
1
概述了如何为企业服务提供门面接口。在这个图中,企业服务
1(enterprise services 1)和企业服务 2(enterprise services 2)访问后端的企业服务系统(EIS)。企业服务
3(enterprise services 3)是门面接口,它可以调用企业服务 1(enterprise services 1)和企业服务
2(enterprise services 2)。
为企业服务提供门面接口的步骤(编号与
图
1
中的一样)如下:
- 创建企业服务并生成访问相应的
EIS 的服务代理 JavaBean 组件。
- 创建门面 JavaBean
组件来调用访问 EIS 的服务代理 Beans。
- 从门面 JavaBean
组件生成企业服务定义。
- 从
步骤 3
中创建的企业服务生成 Web 服务。Web
服务的生成会自动地生成 EJB 组件,这个组件可以用来管理由 EJB 容器执行的事务。
- 为事务管理和指向 J2C
连接工厂的资源引用配置 EJB 组件。
现在,这看起来可能有点抽象。为了具体地演示整个过程,我们将在下面几部分中介绍一个示例。
示例:为 IMS PhoneBook
应用程序提供门面接口
在这个示例中,我们假定您开发的过程中使用的是
WebSphere Studio Application Developer Integration Edition Version 5.0.1,并且更新为 Interim Fix 004
(请参见
参考资料以获得更多关于
Application Developer 更新的信息)。
WebSphere Studio Application
Developer Integration Edition 的帮助系统提供了一个创建用于 IMS
事务的企业服务的示例。相关文档称为“样本:为 IMS 事务创建企业服务”,您可以通过
WebSphere Studio --> Business integration --> Building enterprise services --> Samples --> IMS samples
访问它。在本文剩余的部分中,我将把它称为
Application Developer
文档样本。
您可以遵循这个示例,同时做适当的修改,来创建一个访问 IMS
PhoneBook 应用程序的 Web 服务。
通过 PhoneBook
应用程序,您可以显示、添加和删除 PhoneBook 记录。PhoneBook
接口由输入和输出消息组成,请参见表
1和
2。
表
1. 输入消息
|
字段
|
描述
|
值
|
IN-LL
| Length | 59 |
IN-ZZ
| Flag | 0 |
IN-TRCD
| Transaction code |
IVTNO
|
IN-CMD
| Command |
DISPLAY
或
ADD 或
DELETE
|
IN-NAME1
| Last name | 任意值 |
IN-NAME2
| First name | 任意值 |
IN-EXTN
| Extension | 任意值 |
IN-ZIP
| Zip code | 任意值 |
表 2. 输出消息
|
字段
|
描述
|
OUT-LL
| 长度 |
OUT-ZZ
| 标志 |
OUT-MSG
| 结果消息 |
OUT-CMD
| 命令 |
OUT-NAME1
| 姓 |
OUT-NAME2
| 名 |
OUT-EXTN
| 扩展 |
OUT-ZIP
| 邮政编码 |
OUT-SEGNO
| 段号 |
生成的服务只有通过导入上面的
IMS
接口创建的企业服务定义的一个操作(接口)。访问这个企业服务的客户端无论是显示、添加、删除
PhoneBook 记录,它们都将需要输入上表中所示的
所有输入字段。同时,客户端将接收到所有输出字段的值,这其中可能包括很多对于它们毫无意义的值,即便
IN-NAME1
是惟一的输入变量。
让我们通过使用门面 JavaBean 来将
IMS PhoneBook 应用程序的 Web 服务接口更改为下列接口:
-
displayPhoneBook
-
addPhoneBook
-
deletePhoneBook
生成的服务只有通过导入上面的 IMS
接口创建的企业服务定义的一个操作(接口)。访问这个企业服务的客户端无论是显示、添加、删除
PhoneBook 记录,它们都将需要输入上表中所示的
所有输入字段。同时,客户端将接收到所有输出字段的值,这其中可能包括很多对于它们毫无意义的值,即便
IN-NAME1
是惟一的输入变量。
每个接口都将只有对于客户端有意义的输入和输出消息。
示例概述
这个 Web
服务的示例将为 IMS PhoneBook 应用程序提供上面提及的接口。
图
2 展示了这个服务的概观。
创建 Web
服务的步骤(编号与
图
2 中的一样)如下:
- 为 IMS
PhoneBook 应用程序创建企业服务。
- 创建门面 JavaBean
组件来调用访问 IMS PhoneBook 应用程序的服务代理 Bean。
- 从门面
JavaBean 组件生成企业服务定义。
- 从
步骤 3
中创建的企业服务定义生成 Web 服务。同时生成 EJB 组件。
- 为事务管理和指向 J2C
连接工厂的资源引用配置 EJB。为了支持两阶段提交,您将需要如下软件:
- IMS Connector for Java(IMS 资源适配器),版本 2.1
- IMS Connect,版本 2.1
- IMS,版本 8.1 或更新版本
参考 Application Developer
帮助文档可以获得这方面的更多信息。相关的文档是“使用 IMS
资源适配器的先觉条件”,该文档位于
WebSphere Studio --> Business integration --> Resource adapters --> IMS resource adapter --> Concepts。
- 测试 Web 服务。
- 部署企业服务。
在下面的几个部分中,您可以了解到这些步骤更详细的信息。
步骤
1:为 IMS PhoneBook 应用程序创建企业服务
在
Application Developer
的文档样本中描述了这一步。在企业服务的连接特性中,您可以与样本中描述的一样将
JNDI lookup name
字段置空,但是将它指定为与 WebSphere Application Server
中配置的 JNDI
名相同的名称也是一个好主意,因为在稍后配置 EJB
资源引用时,您需要将 JNDI 查找名称与 JNDI
名相关联。如果您将这个字段置空,则会自动创建这一名称。在这个示例中,将要求您为 WebSphere
Application Server 中的 JNDI 名指定
myIMSTarget 。这样一来,也就为 JNDI 查找名称指定了
myIMSTarget 。
遵循
Application Developer 文档样本中“测试 Java 服务代理”之前(包括这一步在内)的说明。确保 Java
服务代理工作正确。
步骤2:创建门面
JavaBean 组件来调用用于访问 IMS PhoneBook 应用程序的服务代理 Bean
在
步骤 1
中,您在
myIMSPhoneBookService
服务项目中创建了服务代理 JavaBean 组件
sample.ims.myPhoneBookIMSProxy 。在该服务项目中的任何 Java
程序都可以调用这个服务代理 JavaBean。因而,在调用服务代理 JavaBean
组件的服务项目的
facade 包中创建
清单
1 所示的 Facade JavaBean 类。您需要在创建门面 JavaBean
类之前创建
myIMSPhoneBookService 服务项目中的
facade
包。这个示例只侧重于上面提及的接口
displayPhoneBook 、
addPhoneBook
和
deletePhoneBook 。
清单 1.
门面 JavaBean 组件示例
package facade;
import org.apache.wsif.WSIFException;
import sample.ims.*;
public class myPhoneBookFacade {
public static void main(String[] args) {
try {
// Test program
myPhoneBookFacade me = new myPhoneBookFacade();
PhoneBookInfo info;
info = me.displayPhoneBook("LAST1");
System.out.println("LAST NAME: " + info.getLastName());
System.out.println("FIRST NAME: " + info.getFirstName());
System.out.println("EXTENSION: " + info.getExtn());
System.out.println("ZIP: " + info.getZip());
System.out.println("MSG: " + info.getMsg());
} catch (Exception e) {
System.out.println("Error! " + e.getMessage());
}
}
public PhoneBookInfo displayPhoneBook(String lastName) throws Exception {
INPUTMSG input = new INPUTMSG();
input.setIn__ll((short)59);
input.setIn__zz((short)0);
input.setIn__trcd("IVTNO");
input.setIn__cmd("DISPLAY");
input.setIn__name1(lastName);
OUTPUTMSG output = runPhoneBook(input);
PhoneBookInfo info = new PhoneBookInfo();
info.setLastName(output.getOut__name1().trim());
info.setFirstName(output.getOut__name2().trim());
info.setExtn(output.getOut__extn().trim());
info.setZip(output.getOut__zip().trim());
info.setMsg(output.getOut__msg().trim());
return info;
}
public String addPhoneBook(String lastName,
String firstName,
String ext,
String zip) throws Exception {
INPUTMSG input = new INPUTMSG();
input.setIn__ll((short)59);
input.setIn__zz((short)0);
input.setIn__trcd("IVTNO");
input.setIn__cmd("ADD");
input.setIn__name1(lastName);
input.setIn__name2(firstName);
input.setIn__extn(ext);
input.setIn__zip(zip);
OUTPUTMSG output = runPhoneBook(input);
return output.getOut__msg().trim();
}
public String deletePhoneBook(String lastName) throws Exception {
INPUTMSG input = new INPUTMSG();
input.setIn__ll((short)59);
input.setIn__zz((short)0);
input.setIn__trcd("IVTNO");
input.setIn__cmd("DELETE");
input.setIn__name1(lastName);
OUTPUTMSG output = runPhoneBook(input);
return output.getOut__msg().trim();
}
private OUTPUTMSG runPhoneBook(INPUTMSG input) throws Exception {
OUTPUTMSG output;
try {
myPhoneBookIMSProxy proxy = new myPhoneBookIMSProxy();
output = proxy.runPhoneBook(input);
} catch (Exception e) {
String msg;
msg = e.getMessage();
System.out.println(msg);
throw e;
}
return output;
}
private OUTPUTMSG setErrMsg(String msg) {
OUTPUTMSG output = new OUTPUTMSG();
output.setOut__name1("");
output.setOut__name2("");
output.setOut__extn("");
output.setOut__zip("");
output.setOut__msg(msg);
return output;
}
}
|
这个门面 JavaBean 类具有下列接口(方法):
-
PhoneBookInfo
displayPhoneBook(String lastName)
:它用来显示
PhoneBook 记录。
-
String
addPhoneBook(String lastName,String firstName,String ext,String zip)
:它用来添加
PhoneBook 记录。
-
String
deletePhoneBook(String lastName)
:它用来删除
PhoneBook 记录。
可以用
main() 例程将这个类作为运行在非受管环境下的 Java 应用程序来进行测试。
在
displayPhoneBook() 方法中,
PhoneBookInfo
类(如
清单
2 所示)用作返回类,可以为保存有意义的返回值而创建并使用这个类。它具有设置和获取有意义的值的方法。因为
PhoneBookInfo
类的对象是通过 EJB 容器进行传递的,所以它必须实现
java.io.Serializable 。
清单
2. PhoneBookInfo 类
package facade;
public class PhoneBookInfo implements java.io.Serializable {
private String lastName;
private String firstName;
private String extn;
private String zip;
private String msg;
public String getLastName() {
return lastName;
}
public String getFirstName() {
return firstName;
}
public String getExtn() {
return extn;
}
public String getZip() {
return zip;
}
public String getMsg() {
return msg;
}
public void setLastName(String s) {
lastName = s;
}
public void setFirstName(String s) {
firstName = s;
}
public void setExtn(String s) {
extn = s;
}
public void setZip(String s) {
zip = s;
}
public void setMsg(String s) {
msg = s;
}
}
|
您可以通过将
myPhoneBookFacade
类作为非受管环境中的 Java 应用程序进行运行来测试它。
步骤 3:从门面
JavaBean 组件生成企业服务定义
要从门面 Bean
生成企业服务定义,您需要遵循下列步骤:
- 在
Business Integration Perspective的
Service
窗格中,右键单击
Service Projects -->
myIMSPhoneBookService
-->
facade
下的
myPhoneBookFacade.java 。选择
New --> Service built from...。
- 在
Create Service
窗格中选择
Java。单击
Next。
- 选择下面将要公布的方法:
-
addPhoneBook(String,String,String,String)
-
deletePhoneBook(String)
-
displayPhoneBook(String)
然后单击
Next。
- 接受最后屏幕上的缺省设置。单击
Finish。
步骤 4:由企业服务定义产生 Web 服务
由企业服务定义产生 Web 服务:
- 在
Business Integration Perspective的
Service
窗格,右击服务 WSDL 文件
myPhoneBookFacadeJavaService.wsdl ,该文件位于
Service Projects -->
myIMSPhoneBookService
-->
facade 之下。选择
Enterprise Services --> Generate Deploy Code...
- 在
Deployment
窗格,确保
SOAP被选择为
Inbound binding type。
其他选项接受缺省值。单击
Next。
- 在
Inbound Service Files、EJB Inbound Service Files、EJB Port、SOAP以及
SOAP Port
窗格,全部接受缺省值。单击
Finish。
经过这些步骤,在
myIMSPhoneBookServiceWeb 项目中产生了 Web 服务,在
myIMSPhoneBookServiceEJB 项目中产生了 EJB。
步骤
5:为事务管理和资源引用配置 EJB 组件
要配置 EJB,您需要遵循下列步骤:
- 在
Business Integration Perspective的
Service窗格中,右键单击
Deployable Services 下的
myIMSPhoneBookServiceEJB 项目。选择
Open With --> Deployment Descriptor Editor。
- 单击部署描述符编辑器中的
Assembly Descriptor
选项卡。单击
Container Transactions部分中的
Add...。
- 在
Enterprise Bean Selection
面板中,启用
MyPhoneBookFacadeService 复选框。单击
Next。
- 在
Container Transaction Type
和
Method Elements 面板中:
- 首先,查看您的环境是否满足支持两阶段提交的先决条件。您可以通过参考
Application Developer
帮助来获得上述信息;相关文档是“使用 IMS
资源适配器的先决条件”,该文档位于
WebSphere Studio --> Business integration --> Resource adapters --> IMS resource adapter --> Concepts。如果您确实满足这些先决条件,就请为
Container transaction type选择
Required
或
RequiresNew。否则,就选择
NotSupported。要获得关于容器事务类型的更多信息,您可以参考
Application Developer 帮助系统中的另一个文档:“添加容器事务”,该文档位于
WebSphere Studio --> Java and Web development --> EJB development --> Tasks --> Configuring EJB modules using the EJB deployment descriptor editor --> Working in the Assembly Descriptor page。您也可以参看 Richard Monson-Haefel 的
Enterprise JavaBeans(请参见
参考资料以找到它的链接)。
- 为
Methods found
启用下列方法的复选框:
-
addPhoneBook(...)
-
deletePhoneBook(...)
-
displayPhoneBook(...)
- 单击
Finish。
- 单击
References
选项卡。选择
MyPhoneBookFacadeService,然后单击
Add。
- 在
Reference
窗格中,选中
EJB resource reference单选按钮。单击
Next。
- 在
EJB Resource Reference
窗格中:
- 在
Name字段中,键入您在
步骤
1 中为访问 IMS PhoneBook
应用程序的企业服务的连接特性中所指定的 JNDI 查找名称。如果您没有指定 JNDI
查找名称,系统将会自动创建这个名称。对于
Application Developer 文档样本,所创建的名称为
sample/ims/myPhoneBookIMSServicemyPhoneBook 。如果您还没有指定 JNDI
查找名称,就请键入这个名称。(要获得更多的信息,请参考
Application Developer 帮助文档“J2C 资源适配器服务的管理”,该文档位于
WebSphere Studio --> Business Integration --> Building enterprise services --> Concepts --> Process of building an enterprise service。您也可以参考 IBM
红皮书“Exploring WebSphere Studio Application Developer,Integration Edition 5.0”;请参见
参考资料以获得它的链接。)
- 为
Type选择
javax.resource.cci.ConnectionFactory。
- 为
Authentication选择
Container。在配置您的 WebSphere 应用程序服务器时,您需要指定 JAAS
验证。
- 为
Sharing scope选择
Shareable。要获得更多关于共享作用域的信息,可以参考
Application Developer 帮助文档“不可共享的和可共享连接”,该文档位于
WebSphere Application Server Enterprise --> Product features --> Resources --> Data access --> Accessing data from applications --> Connection management architecture。
- 单击
Finish。
- 在
WebSphere Bindings
部分,为
JNDI name 键入
myIMSTarget 。
- 按 Ctrl-S
保存您所作的更改。
步骤
要测试 Web
服务,您需要首先创建测试服务器,如 Application Developer
文档样本所述。在样本中完成以下部分:
- 创建并配置服务器实例。
- 将连接工厂添加到服务器配置中。
- 将 EAR
项目添加服务器配置中。
您还需要配置验证,如下所示:
- 通过双击
Server Configuration
视图的
Server Configuration 选项卡中的
myIMSServicesServer 来打开
myIMSServicesServer 配置编辑器。
- 选择
Security
选项卡。在
JAAS Authentication Entries部分中,单击
Add。
- 在
Add JAAS Authentication Entry
面板中:
- 为
Alias 键入
myIMSAuth 。
- 为
User ID键入 IMS userID。
- 为
Password键入 IMS password。
- 单击
OK。
- 选择
J2C
选项卡。在
J2C Resource Adapters 部分中选择
IMSConnector 。在
J2C Connection Factories
部分中选择
ims_cf 。此外,单击
Edit。为
Container-managed authentication alias 选择
myIMSAuth 。如果应用程序没有提供用户
ID和密码,您也可以为
Component-managed authentication alias
选择
myIMSAuth ,这个选项用于组件管理的环境。单击
OK。
- 按 Ctrl-S
保存所作的更改。
要创建 Web
服务客户端,您需要遵循下列操作:
- 在
Business Integration Perspective的
Services
窗格中,右键单击
Deployable Services 下的
myIMSPhoneBookServiceWeb 项目。选择
New --> Other...。
- 在
Select
面板中,在左边窗格选择
Web Services。然后,在右边窗格选择
Web Service Client。单击
Next。
- 在
Web Services
面板中,确保
Client proxy type为
Java proxy。单击
Next。
- 在
Web Service WSDL File Selection
面板中,单击
Browse...。选择
myIMSPhoneBookServiceWeb
--> Web Content --> wsdl -->
facade
-->
myPhoneBookFacadeSOAPService.wsdl ,然后单击
OK。单击
Next。
- 在
Web Service Binding Proxy Generation
面板中,启用
Generate proxy
复选框。禁用其他的复选框。接受其他缺省值。单击
Next。
- 在
Web Service Test
面板中,启用
Test the generated proxy和
Run test on server
复选框。接受其他缺省值。单击
Finish。
现在,
图
3 所示的 Web
页自动生成,可以用来测试您在上面的步骤中刚刚创建的 Web 服务。要了解它是如何工作的,可以单击
Methods
窗格中的
displayPhoneBook 。为
Inputs
窗格中的
lastName 键入
LAST1 ,然后单击
Invoke。返回值显示在
Result
窗格中。
如果您稍后想要测试该 Web
服务,您可以通过下列步骤来访问它:
- 在
Business Integration Perspective的
Package Explorer
选项卡中,展开
myIMSPhoneBookServiceWeb
--> Web Content -->
sample
-->
myPhoneBookFacadeSOAP 。
- 右键单击
TestClient.jsp。选择
Run on Server...。
步骤
7:部署企业应用程序
您可以按照与 Application
Developer 文档样本相同的方式来部署企业服务。
当您完成部署时,可以利用 Web
浏览器来测试 Web 服务(通过您利用 Application Developer
Integration Edition 测试过的 Web 页)。您可以添加、删除或者显示 PhoneBook
记录,如
图
4 所示。
结束语
本文描述了一种为企业服务提供门面接口的方法。可以使用门面
JavaBean 组件来调用多个企业服务和 JavaBean
组件。通过使用门面 JavaBean
组件,您也可以给客户端提供接口(操作),其中每个都代表一个工作单元。当您想要集成多个
EIS、更改由企业服务生成的接口或者添加一些与企业服务或 JavaBean
组件一起工作的逻辑时,您就可以使用门面 JavaBean
组件。您现在很可能对如何创建 Web 服务有了进一步的理解,Web
服务能够释放后端企业系统的能力,同时过滤掉终端用户不想要的额外信息和选项。
参考资料
关于作者  | |  | Masahiro Ohkawa 是日本 Yamato 软件开发实验室(YSL)的一名软件工程师。他是该实验室中 DB2 信息集成器(DB2 Information Integrator)开发组的一员。Masahiro
的经验包括参与了客户端/服务器和中间件产品的开发、J2EE
应用程序开发以及访问企业信息系统。 |
对本文的评价
|