未定
设计组件
Notes/Domino 有几个关键组件:导航器、代理、表单、视图和安全性。在 Web 上复制导航器非常容易,因为导航器最初是为了使 Notes 看起来像 Web 而设计的。代理功能是业务逻辑,可以在 J2EE 中相应地实现。这一节讨论了表单和视图的创建,以及 J2EE 环境中的安全性设计。
表单
一个表单由一个前端、中间件和一个后端组成。
- 前端
- 以前的文章已经讨论过,Apache Struts 是处理前端表单输入的一个极好的工具。我在本文中再次使用了 Struts。图 1 显示了如何读取、创建、编辑和删除文档。
Struts 模型-视图-控制器(Model-View-Controller,MVC)模型接受用户输入,通过验证,然后通过它的操作 servlet 创建一个包含表单上每个域的 Java bean(表单 bean)。通过在 JavaServer Page(JSP)页面上用 JavaScript 编程能获得客户机端的验证。我们还创建了一个自己的标记库来创建几个独一无二的 Notes 功能,例如:选择列表和对话框。多文本域(rich text field)是 Notes 独有的,允许用户用不同字体输入文本和添加附件。在 Web 上,和许多邮件程序所演示的一样,可以把附件逐个添加到一个电子邮件消息上。(我不打算在本文中讨论过多细节,因为有许多现有的软件包能处理这个问题。)
在 Notes 中构建行项有点儿困难;通常是通过构建一个大型表并且用“何时隐藏”公式隐藏空行来实现的。对于在一个表单上能放多少个行项有一个限制。另一方面,在 Struts 中,在一个表单内构建行项相当容易。只需在会话、请求或页面属性中放入一个 bean 数组,Struts 就会逐行为您构建一个表。当用户选择添加一个行项时,表单不经验证就被提交并且放在一个临时存储器中。在添加这个行项后,临时表单将被刷新,所以用户能看到变化。
- 中间件
- 复制助手 Java bean 可以用于将数据从 Enterprise JavaBean(EJB)传送到 servlet。这种类型的 Java bean 将有助于层隔离。前端开发者可以用来自复制助手 bean 的伪数据开发 JSP 页面和表单 bean。同时,后端开发者可以为复制助手 bean 开发 EJB。当两方面都就绪时,您只需要用真实的 bean 替换带有伪数据的 bean。
- 后端
- 用实体 EJB 从数据库中读取、创建、修改和删除文档。请注意,我们用一个会话 bean 将数据传给多个实体 bean 供它们读取和更新,见图 1,所以会话需要调用多少实体 bean 就可以调用多少来完成表单更新。这种设计的另一个优点是您可以把实体 bean 和中间件隔绝开。EJB 2.0 规范对容器管理的持久性(CMP)的实体 bean,例如:EJB-QL,容器管理关系(Container Managed Relationship,CMR)以及本地接口,作了很多主要改进。当下一个版本的 WebSphere 实现 EJB 2.0 规范时,您无需更改任何中间件或前端代码就能更新实体 bean。
视图
前端 Notes/Domino 拥有最复杂的可用导航设计之一。在 Web 上,几乎没有几个地方使用类似 Notes 的方式浏览有序的列和分类的列;多数只不过使用一个搜索功能。因为在 WebSphere 中复制 Notes 视图并不容易,如果您的用户能一直使用一个类似 Web 的搜索功能,将会简化转换进程。
如果您决定在 WebSphere 中复制 Notes 视图,要经过几个步骤。我们构造一个专门的标记库来构建标准的、分类的并且有日历风格的视图。我们甚至扩展标记库使其包含几个 Notes/Domino 中不常见的功能。例如:我们在一个分类的列中有两种排序类型。用户可以对一种类别的文档进行排序,或者对视图中所有的文档进行排序。因为用户能够对任何列进行排序,所以需要高速缓存来将性能最大化。我们的中间件软件提供了视图导航,包括页面和排序。
自从有了 Domino 版本 5,您就可以选择选项来使用一个基于 Java applet 的视图。转换一个基于 applet 的视图相当容易;您可以以最低花费在线购买许多导航 applet,而且某些情况下这些导航 applet 甚至还带有源代码。1997 年,当我和我的同事 Charles Jones 在 IBM 一起工作时,我们首先采用一个 applet 对一个基于 Notes 的目录数据库进行导航。然而,applet 有众所周知的缺点:它们速度慢且不稳定。现在使用的 Domino 视图多数仍然是 HTML 格式。图 2 显示了视图设计的图表。
- 中间件和后端
- rowset Java bean 用于在 servlet 和 EJB 之间传送数据。EJB 将成为一个 bean 管理的和有状态的会话 bean,将性能最大化。一个 bean 管理的 bean 给了我们在一次批处理内传送一块数据并把这块数据送到前端的可能性。请用有状态的会话 bean 维护页面信息,这样当用户逐页浏览文档时,引导用户转向正确的页面。
为了提高效率,我们建议您在关系数据库内为缺省的 Notes 视图排序维护一个预构建的视图。
项目 | 操作 |
读安全性 | 我们建立了 EJB 级别的安全性,从而只读取视图内允许特定用户读取的文档。 |
写安全性 | 当用户单击编辑按钮时,必须构建逻辑来实时检查用户的权限。如果用户有适当的访问权限,文档以编辑模式返回;否则,发出一条错误消息。 |
记录锁定 | 与 Notes 不同,可以通过部署标准技术经由后端关系数据库获得。 |
工作流 | 也可以通过许多可用的基于 Java 体系结构的工作流包获得。 |
搜索 | 可以作为一个标准关系数据库搜索来实现。但是,如果您想在附件中有搜索功能,则需要定制搜索功能。 |
示例
现在来看一个真实的示例。几年前,考勤卡应用程序是用 Notes 写的。从那以后,该程序已经变成了一个非常大的数据库,我们现在需要把它和一个中央 DB2 数据库以及工资单的 SAP 集成在一起。通过将基于 Notes 的应用程序转换成一个基于 WebSphere 的应用程序,我们可以解决性能和集成的问题,因为 WebSphere 有一个到 DB2 的直接 JDBC 连接以及一个来自 IBM 或 SAP 的 SAP 连接器。
示例表单
以前提到过,表单是基于 Struts 的。这是一个典型的 Struts JSP 头和一个输入域。tojava.tld 文件描述了我们定制的 JSP 标记库。
|
图 3 显示了一张考勤卡。
图 4 显示了读模式下的考勤卡表单。
图 5 显示了编辑模式下的考勤卡表单
这些域由一个 Struts 表单 bean 管理。
|
我们构建了自己的标记库来处理一些 Notes 特有的功能。例如:对一个对话框的编码如下:
|
图 6 显示了考勤卡表单对话框。
和其他通用标记库相似,当构造 HTML 页面时,用属性把数据传送给 Java 代码。属性 imagedir 引用存储图像文件的目录。属性 formname 是包含域的表单的名称,inputproperty 是供选择的域的名称。如果需要受支持属性的一个完整列表,请参考 tojava.tld 文件。我们还为 Notes 的“选择列表”提供了一个标记库。
对于一个行项,您只需用我们在 Struts 样本代码中看到的 Struts iterate 标记。下面是完整的源代码:
|
timeSheetDoc 是一个存储所有与文档相关的属性的文档 bean。它包括 timeItems,timeItems 存储 Struts 要迭代的行项数组。在迭代循环中,我们根据表的各列列出了属性。最后,我们添加了一个删除任意项的删除链接。图 7 显示了考勤卡表单的行项。
最后,我们构建了一个 Struts 操作类来读取、编辑并创建表单输入。
|
示例视图
结果视图大部分都是用我们自己的标记库构建的,这个库支持分类的、常规的和日历风格的视图。下面是一个分类视图的示例。
|
图 8 显示了考勤卡视图。
我们使用一个视图-视图循环-视图项(view-viewloop-viewitem)结构。视图标记用来显示与视图相关的功能,例如:视图导航、每页的行数等等。status
属性初始化视图的最初状态。视图循环启动实际循环。视图项通过传送域名称、类别、复选框选项等等来显示实际项。您可能注意到了,我们扩展了 Notes/Domino 视图,使其具有两种不同的排序。为了运行宏对其进行批处理,我们还添加了在每个文档前面有一个复选框的选项。
TimeSheetViewAction
类的写法如下:
|
ViewAction 是一个抽象类,处理所有的通用视图功能和导航。必须在子类中实现的四种抽象方法:
initialized()
- 初始化视图,将 url 转发字符串和第一次排序的域名传给视图。
CreateForms()
andCreateDocs()
- 从数据库载入初始数据(通常通过 EJB)到 Struts 表单 bean 和文档 bean。
RebuildView()
- 处理文档删除。