许多应用程序都具有这样一个共同特征,即包括了一系列的步骤,或者“状态”。用户以及其他系统所参与的交互制约着这些步骤之间的转换。像这样的应用程序实例包括:
Order Entry(订单输入):用户根据产品目录的信息创建一个在线订单。然后用户将这个订单提交给库存管理来预订相应的产品并获得最终的报价单。然后,用户将作出购买或者取消的决定。如果用户决定购买,则系统会继续执行下去进行订单分解、Backorder 等处理。
User Registration(用户注册):在各式IT系统中,一位新用户(如一位新雇员)必须经过注册来创建账户和概要文件(profile)。应用程序会提示用户根据已经存储到雇员数据库中的信息输入信息,比如,全职雇员必须注册(sign up)才能获得相关的好处、库存采购计划等,但合同员工(contractor)不能执行此操作。根据优先选择以及这些后端系统的具体要求,用户的数据会再一次提交到许多不同的后端系统中。最后,用户会收到在各种后端系统中注册进度的报告,用户还可能会根据需要输入更多的信息。
这里有若干实例。具有该基本特征的用例是非常多的。在本文中,我们将考察如何利用WebLogic Workshop中有关Java过程的定义来进行此类应用的开发。
示例应用程序:Order Entry
让我们来仔细了解一下这个示例程序。图1展示了订单输入向导的页面流。所谓页面流基本上是指关于Strut控制器及其相关JSP文件的图形化表示。简单地讲,它定义并展示了Web应用是如何从一个页面流到另一个页面的。下面,让我们顺着订单输入的页面流走一趟:
- 用户从begin动作开始并被立刻发送到Greeting页面。从这里,用户通过getProducts动作到达orderProducts页面。
- 用户为在线订单进行相关产品的选择,完成订单后继续到checkout。
- 在checkout阶段,该应用程序与库存管理系统进行联系来为这个订单预定相关的库存产品,同时访问客户数据库和产品数据库获取客户和产品的有关信息,以便计算出相关的小计和总计信息。
- 为了获得最大限度的可伸缩性和健壮性,所有这些操作都是异步执行的。同时,浏览器将不断的轮询这个Web应用程序,直到该应用程序从后端系统获得结果。这是用pollCheckoutResponse动作在waitForCheckout页面完成的。
- 当后端系统准备好后,就能向用户提供最终的订单,供用户复审。这项工作是在showCheckedOutOrder页完成的。此时,用户可能会需要一定的时间来对本次购买做出决定。与此同时,系统已经对订单中包含的相关库存产品进行了预定,这样,就能够使用户按照订单完成本次采购活动。
- 当用户最后做出决定时,会发生如下一些事情
- 用户取消本次订单——进行cancelOrder动作。此时,系统必须取消对库存系统中存货的预订,然后将用户恢复到开始状态。
- 订单超时,因为用户做决定所用时间过长而同时应用又不能无期限地预定库存。存货由库存系统取消预定,如果用户通过转至placeOrder动作继续订购的话,该动作将会检测到超时并将用户送到timedOut页面。
- 用户适时转至placeOrder动作可以继续订购。
- 如果用户决定在有效时间内继续订购,则应用程序会执行placeOrder动作,将订单提交到各个后端系统进行执行。像前面一样,此动作是采用异步方式执行的,所以当订单正在处理时,浏览器会展示一个等待页面——waitForOrderPlaced,它通过执行pollOrderPlaced动作对该Web应用程序进行轮询。
- 当后端系统完成订单处理时,它们就会响应Web应用程序并将响应内容利用orderPlaced页面展示给用户。
图1:Order Entry应用程序的页面流
实现的挑战是什么?
到现在为止,我们只是看了看来自前端的这个应用程序流。但是毫无疑问,如果要实现前面隐式和显式描述的所有逻辑将会有很多挑战。
首先,我们并没有明确说明如何访问各个后端系统。其次,我们要完成许多的异步操作,而众所周知这在J2EE环境中是困难的。第三,我们还需要以某种方式来管理状态。让我们看一看这些挑战并考虑如何解决它们。
访问各类系统资源
任何构建过企业级应用的人都清楚,与现有系统进行连接并进行数据交换可能是一个非常复杂的问题。有许多技术都用于解决这类问题,包括JDBC、JCA、Web services、JMS以及其他更多的专业API。
那些构建这类应用的开发人员需要的是更加通用和简便的技术。他应该不用关心如何与底层系统进行连接这类细节。毕竟这是一种探究性的工作,应该通过基础结构来对其进行处理。
当使用BEA WebLogic Workshop构建应用程序时,您可以使用Java Control来提供对底层资源的泛化和简化的抽象。当然您仍需要编写Java控件来访问后端系统,但是在Workshop中已经包含了那些最常用的控件,所以并不太需要这样做。例如,您利用内置控件访问EJB、JDBC数据资源、Web服务和JMS Destination。
不管是构建控件还是该控件已经存在,对于应用程序开发人员来说,采用控件确实简化了对系统资源的访问。这样就能够轻松定义那些既可以供应用工程师使用也可以供系统工程师使用的可重用组件。
异步操作
为了获得最大程度上的健壮性和可伸缩性,订单输入向导必须以异步方式来对后端系统进行访问。因为当连接很多系统时,如果总是同步执行操作,则会导致意想不到的延迟,甚至死锁问题。通过使用异步调用,底层系统中的操作在执行时,与用户和其他任何在应用程序中运行的代码进行的交互操作无关。
现在的问题通常是实现这些异步操作并不容易。在J2EE中,不应直接使用线程,所以仅仅创建一新线程是行不通的(这一点很有意义)。在J2EE中,正确实现异步操作的方法是使用JMS和消息驱动的Bean(MDB)。但是这样做会非常繁琐,涉及建立JMS Server和JMS目标。在客户端,您必须实例化上下文和Factory对象,而且一般还要了解如何使用JMS API。在接收端,您需要实现完全独立的MDB来接收消息并执行操作。这不仅是困难的,而且还将您的代码分散到若干新的组件中,这样就导致对代码的阅读和维护工作难以进行。仅由于需要以异步方式调用这一个原因而将您的业务逻辑的某部分放到完全不同的组件中,这种做法是不合理的。
当然您可以采用一些技术在一定程度上修正这个问题。但这是额外的工作,而您已经花费了非常多的精力只是实现了基本的异步。
幸运的是,当您使用Java 控件和WebLogic Workshop时,问题就变得不再那么困难了。因为关于Java 控件的操作能够轻松的以异步方式进行。它会准确地按照前面所描述的执行。底层的Workshop 运行时框架完成了那些涉及MDB和JMS的探测工作。我们无需了解JMS或者MDB的技术细节。
过程和状态管理
我们称这订单输入向导就是所谓的过程驱动的型应用,因为该程序是由遵循一定过程的步骤所组成的。过程中不同结点间的转换受到用户决定以及系统信息的制约,也就是说,是否超时以及库存中是否有足够的存货。
当构建这样的应用程序时,需要解决一些问题。在任何时候程序都必须了解自己处于哪个状态中,这个状态可能对于其他系统也非常重要,而不仅是对用户重要。此时,它的影响不仅局限于用户:如果丢失该状态,那么相应的存货就不能正确地返回给库存,这样会导致实际库存与库存管理系统不一致。
该状态属于业务关键型信息。需要时,此类状态必须持久保存,而且为了遭到破坏,只能以事务处理的方式对其访问。这与保存在HTTP 会话和安全性相对较弱的位置的用户会话状态是完全不同的。因为如果丢失用户会话的状态,受影响的只是用户而不是系统状态。
除了状态管理,还有许多其他问题需要您还处理,比如异常处理、聚类以及如何在哪个状态下执行哪个操作等。
有了WebLogic的帮助,您不用亲自动手编写所有的这些代码。当需要创建构建过程时,您可以借助于WebLogic Workshop的Java Process Definitions。过程定义把所有这些需求以及更多功能都内置到框架中,所以您可以将精力集中到过程的设计方面而让框架做其余的工作。
监视
借助于这个已经定义好的驱动应用程序的过程,您能更多地监视应用程序。WebLogic允许您在给定时间段内监视所有正在运行的过程实例,而且您还能查看那些已经结束运行的过程的历史数据。您所能监视的内容包括
- 过程实例的完成时间
- 过程实例中某个结点的完成时间
- 过程实例当前所处等待的位置
- 过程实例是否超越了本身的服务级协议
- 发送给过程实例的数据
- 过程实例所包含的数据
管理控制台只提供了众多监视功能的其中一部分。
使用不同的XML和Java数据模型
我们在前面谈到了关于连接到许多不同后端系统的问题。然而,仅仅讨论关于这些系统的调用操作和接收响应是远远不够的。当使用某个后端系统的API的时,不管该系统采用了哪个数据模型,都必须进行相应的处理。当您向它发送数据时,它应该根据系统定义的某种格式存储该数据。一般情况下有两种格式,一种是作为数据容器的Java类图,另一种则是利用XML Schema定义的XML格式。
这里的问题是您的应用程序不太可能都使用完全相同的Java类或者XML对象集,而可以确定您所需要交互的后端系统绝大多数情况下并不使用相同的数据类型。每当接收到用户的数据并将其发送到某个后端系统时,您必须从数据图中提取出数据图所有的元素,然后将其重新装配成特定系统能够理解的数据对象。当您每次从一个系统接收数据并转发到另一个系统或者回送到用户时也会经历同样的事情。这里牵扯到了很多需要手动完成的工作,而且当数据格式发生变化时,很难对其进行重用和维护。
现在,您可以利用一些技术来简化这项工作。这些技术是
- XML Beans
- XQuery
- Visual Data Transformation Designer
XML Beans是一个框架,BEA已经依据Apache许可协议将其发布到开放源代码社区,该协议允许将XML文档作为Java对象来使用并能够将XML解析成Java 图以及从一组Java对象生成XML文档。
您可以将XML Bean完全从WebLogic环境中分离出来,它是内置到WebLogic和WebLogic Workshop中的,因此可以从XML 架构文件动态地创建XML bean。这样使得将数据从XML文档转换到Java对象变得异常简单。
一旦将数据表示成XML Bean,就可以通过XQuery表达式来访问数据图的各个元素。这样就对提取单个数据项或复杂数据重复集提供了强有力的支持。XQuery是一个由许多软件库和厂商支持的标准,因此可以在不同的环境中重用XQuery表达式来表示相同的数据提取结果。
最终的和最有力的工具是数据转换控件以及可视化设计器,使您能以一种直观的方式设计数据转换。这个工具充分利用XML Bean和XQuery的强大功能,向您展示了源对象图和目标对象图,您可以在两个图中的两个元素之间加上连接器。因为所构建的转换实际上是一个控件,所以当您需要执行同样转换时,就能够实现该控件的重用了。因此,即使该转换在应用中被广泛的使用,您也只需要在一个地方维护转换即可。
相关讨论
到目前,我们已经讨论了有关过程驱动的应用程序在实现方面的挑战。其中关键的一点是:这种应用程序非常有代表性,我们已经浪费了太多的时间来不断地重新实现同样的框架、模式和服务,而所有这些对于过程驱动的应用来说都是相同的。引入Java过程定义概念后,您可以精力集中编写过程,而让基础结构处理其余的工作。
目前,Java Community Process正展开Java 过程定义的标准化。JSR 207 “Process Definition for Java”(或简写为PD4J)是一个被广泛支持的标准,包括IBM在内的众多厂商共同制定了如何在注释过的Java源代码中进行过程定义。现在已经达成了这样一个共识,企业基础结构必须对构建和运行过程提供直接的支持。这将是未来IT系统的构建方式。这是从旧时的、僵硬的应用程序向构成企业信息网的“流动”的服务和数据迈出了很好的一步。
| 作者简介 |
|
Jesper Joergensen是具有超过7年的Java企业软件工程和营销经验。 他在2年前加入BEA作为产品推广人员,重点关注WebLogic平台上的面向服务体系结构。在加入BEA之前,Jesper是Caput的CTO,这是第一批在WebLogic上启动真正的ISV产品项目的欧洲公司之一。他有5年时间在Caput负责技术和产品,这家公司原先只是一家本地的创业公司,在他的帮助下成长为在WebLogic应用服务器平台上为合作解决方案提供J2EE组件的全欧性厂商。 |
|