站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2EE 专题J2EE探索 有状态网络的J2EE技术

J2EE探索 有状态网络的J2EE技术

摘要: J2EE探索 有状态网络的J2EE技术

有状态应用程序管理
您可能会回想起来,在上一篇文章中,Web 应用程序协议被分成两大类别:无状态(stateless)和有状态(stateful),协议的状态指的是它“记忆”从一个传输到下一个传输的信息的能力。因为有状态连通性是大多数企业应用程序的基本需求之一,并且因为 Web 应用程序依赖于 HTTP(内在的无状态协议),所以聪明的开发人员已经找到了许多技巧来在 HTTP 上模拟有状态连接。有状态信息可以存储在 HTML 表单字段中、附加到超链接或者存储在客户机端的 cookie 中。

客户机和服务器之间的有状态交互可以在 Web 层或业务层上进行管理。要在 Web 层上管理状态,我们使用与 HTTPSession API 结合的 servlet。要在业务层上管理状态,我们使用有状态会话 EJB 组件。在接下来的章节里,我们将探究这两种开发选项。

Web 层
Servlet 体系结构的 HTTPSession API 允许应用程序开发人员管理跨网络的客户机/服务器交互(或会话)的状态。HTTPSession 接口定义了 HTTPSession API 的核心功能。它为 J2EE 应用程序提供了一种方法,使它可以识别跨多个页面请求的单个客户机,以及将数据存储在与那个客户机相关联的服务器上。通过该接口,servlet 容器创建和管理客户机和服务器之间的会话。该会话由 HTTPSession 对象表示,它可以跨来自相同客户机的多个连接和页面请求持续存在一段特定的时间。Servlet 使用该接口来查看与处理有关会话的信息,如创建时间和上一次访问会话的时间。该接口还允许 servlet 将对象绑定到会话,从而以一种跨多个连接(来自相同客户机)持续存在的方式将该信息与特定的客户机进行关联。

Servlet 体系结构
Servlet 体系结构并没有因为使用 HTTPSession API 而发生改变。就象在无状态网络中一样,servlet 代表客户机执行业务请求,并且充当控制器、视图,或者二者同时兼任。Servlet 还可以有效地处理用户交互,如内容格式化和显示、基本请求处理和安全性请求及更多。就象在无状态网络中一样,servlet 最好用于管理客户机交互,那么通常可使用助手类(如 JavaBeans)来应付繁重的处理或者与后端组件相互操作(interface)。
因此,HTTPSession 接口允许 servlet 容器创建和管理客户机会话,并且使 servlet 能访问与会话相关的信息、将对象绑定到会话以及访问先前绑定的对象。到现在为止,一直都还不错。但是 servlet 容器如何跟踪通过无状态协议(如 HTTP)通信的客户机呢?为了实现这一点,为每个 HTTPSession 对象都提供一个唯一的标识,以确保每个客户机会话和与会话相关的数据可以被唯一标识。考虑到 HTTP 内在的无状态本质,在每次请求时,该会话标识必须被客户机传递给服务器,以便于 servlet 容器将客户机与正确的会话相关联。会话标识可以用三种方式中一种进行传递:作为 HTML 表单中的参数(通常是隐藏字段);作为附加在查询字符串后的参数;或者作为 cookie 的属性。不管会话标识如何传递,servlet 容器都将拦截它,检查它,并找到与之关联的 HTTPSession 对象。

Servlet 性能
由 Servlet 体系结构创建的轻量级线程模型决不会因为 servlet 或 JSP 文件创建、读取或修改 HTTPSession 对象而受到破坏。该对象只是将对象引用存储为简单键-值对的散列表或类似的集合。同样,HTTPSession 内存空间的实现本身也是轻量级的,只需要存储(或许序列化)会话对象和相应的会话标识。简而言之,servlet 可以支持与 HTTP 客户机的有状态交互,而且对应用程序设计或容器资源产生最小的影响。
有状态应用程序管理
您可能会回想起来,在上一篇文章中,Web 应用程序协议被分成两大类别:无状态(stateless)和有状态(stateful),协议的状态指的是它“记忆”从一个传输到下一个传输的信息的能力。因为有状态连通性是大多数企业应用程序的基本需求之一,并且因为 Web 应用程序依赖于 HTTP(内在的无状态协议),所以聪明的开发人员已经找到了许多技巧来在 HTTP 上模拟有状态连接。有状态信息可以存储在 HTML 表单字段中、附加到超链接或者存储在客户机端的 cookie 中。

客户机和服务器之间的有状态交互可以在 Web 层或业务层上进行管理。要在 Web 层上管理状态,我们使用与 HTTPSession API 结合的 servlet。要在业务层上管理状态,我们使用有状态会话 EJB 组件。在接下来的章节里,我们将探究这两种开发选项。

Web 层
Servlet 体系结构的 HTTPSession API 允许应用程序开发人员管理跨网络的客户机/服务器交互(或会话)的状态。HTTPSession 接口定义了 HTTPSession API 的核心功能。它为 J2EE 应用程序提供了一种方法,使它可以识别跨多个页面请求的单个客户机,以及将数据存储在与那个客户机相关联的服务器上。通过该接口,servlet 容器创建和管理客户机和服务器之间的会话。该会话由 HTTPSession 对象表示,它可以跨来自相同客户机的多个连接和页面请求持续存在一段特定的时间。Servlet 使用该接口来查看与处理有关会话的信息,如创建时间和上一次访问会话的时间。该接口还允许 servlet 将对象绑定到会话,从而以一种跨多个连接(来自相同客户机)持续存在的方式将该信息与特定的客户机进行关联。

Servlet 体系结构
Servlet 体系结构并没有因为使用 HTTPSession API 而发生改变。就象在无状态网络中一样,servlet 代表客户机执行业务请求,并且充当控制器、视图,或者二者同时兼任。Servlet 还可以有效地处理用户交互,如内容格式化和显示、基本请求处理和安全性请求及更多。就象在无状态网络中一样,servlet 最好用于管理客户机交互,那么通常可使用助手类(如 JavaBeans)来应付繁重的处理或者与后端组件相互操作(interface)。
因此,HTTPSession 接口允许 servlet 容器创建和管理客户机会话,并且使 servlet 能访问与会话相关的信息、将对象绑定到会话以及访问先前绑定的对象。到现在为止,一直都还不错。但是 servlet 容器如何跟踪通过无状态协议(如 HTTP)通信的客户机呢?为了实现这一点,为每个 HTTPSession 对象都提供一个唯一的标识,以确保每个客户机会话和与会话相关的数据可以被唯一标识。考虑到 HTTP 内在的无状态本质,在每次请求时,该会话标识必须被客户机传递给服务器,以便于 servlet 容器将客户机与正确的会话相关联。会话标识可以用三种方式中一种进行传递:作为 HTML 表单中的参数(通常是隐藏字段);作为附加在查询字符串后的参数;或者作为 cookie 的属性。不管会话标识如何传递,servlet 容器都将拦截它,检查它,并找到与之关联的 HTTPSession 对象。

Servlet 性能
由 Servlet 体系结构创建的轻量级线程模型决不会因为 servlet 或 JSP 文件创建、读取或修改 HTTPSession 对象而受到破坏。该对象只是将对象引用存储为简单键-值对的散列表或类似的集合。同样,HTTPSession 内存空间的实现本身也是轻量级的,只需要存储(或许序列化)会话对象和相应的会话标识。简而言之,servlet 可以支持与 HTTP 客户机的有状态交互,而且对应用程序设计或容器资源产生最小的影响。

选择合适的技术
与无状态的 J2EE 体系结构不同,J2EE 应用程序不提供典型的配置来充当指南或蓝图。管理状态时,合适的体系结构取决于下列因素:

客户机是基于 Web(HTTP)的吗?
对话状态需要包含到 GUI 中吗?
服务器将处于哪种负载条件下呢?
有状态组件需要能够在服务器崩溃后仍然有效吗?
该组件需要哪种事务上下文呢?
有状态数据有多重要?
尽管上述一些问题似乎明显地倾向于其中一种技术,但是许多有状态方案实际上既需要使用 servlet 又需要使用 EJB 组件。至关重要的决定就是确定是在 Web 层还是在业务层上管理状态,或者同时在两个层上管理状态。在下一节中,我们将研究一些可能的企业应用程序方案,及其最适宜的解决方案。

应用程序客户机
标准的应用程序客户机是与另一个系统或组件相互操作的客户机。我们将研究三种典型的应用程序客户机方案,并且讨论每个客户机最适合的有状态解决方案:

如果客户机是基于 Java 的,并且与服务器处于相同的防火墙之后,那么您首先应该决定有状态交互模型是否是必需的。管理有状态会话 bean 是资源密集型的,因此您应该考虑更轻量级的备用方案。最佳解决方案就是使用 RMI 直接与应用程序服务器中的无状态会话 bean 对话。如果有状态解决方案是必需的,则请考虑使用带有简单事务层的无状态会话 bean,或者在业务层上创建瘦 servlet 层。任何一种解决方案花费部分成本即可提供有状态体验。最后,如果您的客户机必须与跨多个请求的业务过程的状态进行紧耦合,并且不能接受添加 Web 层,那么有状态会话 bean 是显而易见的选择。

如果您正在使用非 Java 的客户机或者使用与服务器不在同一个防火墙之后的客户机,那么状态管理问题略有不同。在这种方案中,您首先应该确定状态管理的目标。如果目标是通过某种 GUI 为用户提供流畅的体验,那么您可以在 Web 层上管理状态。如果目标是将跨多个请求的复杂业务过程联系在一起,那么状态管理应该在业务层上进行。再次强调,您应当始终探索其它选项,如使用带有事务层的无状态会话 bean。

一些应用程序服务器供应商以一种诸如接受本机 IIOP 调用的方式公开 EJB 容器,从而允许 CORBA 客户机将 EJB 组件当成本机 CORBA 应用程序。这允许非 Java 客户机使用 IIOP 协议与无状态会话 bean 进行通信。在该设置中,客户机绕过了 Web 层,并使用 IIOP 协议直接与业务层(会话 bean)进行通信。这时,体系结构分析与位于防火墙后的基于 Java 的应用程序分析是相同的。请参考第一种方案,以理解业务层上的状态管理问题。

电子商务随需应变环境
正如我们上个月讨论的,无状态会话 bean 是为电子商务随需应变(e-business o­n demand)应用程序精心设计的。它们是非常轻量级的,可以轻松地汇聚为池,以确保卓越的可伸缩性。相反,有状态会话 bean 并不是为这类应用程序而精心设计的。电子商务随需应变应用程序中通常需要状态管理,但是最好由专用的机制或通过 J2EE 事务进行处理。另一种可能性是调用 EJB 组件,就好象它是 CORBA 组件一样。当一个或多个被集成的应用程序是 CORBA 组件时,该选项特别有用。

“富”GUI 客户机
有三种基本的“富”GUI(不是 HTML,也不是命令行)客户机类型:Java applet、独立应用程序和 Java Web Start。下列解决方案适用于这三种“富”GUI 组件类型中的任何一种:

如果您的客户机和服务器被防火墙分隔,您应该让客户机通过 HTTP 与 servlet 直接通信。该 servlet 层可以使用助手类应付简单的业务处理。如果您的应用程序有更复杂的需求,或者对企业资源有更高的请求频率,您应该使用会话 bean 来处理业务过程。这里再强调一次,您应当将有状态交互模型的必要性作为决策过程的一部分进行考虑。


如果您的客户机和服务器位于同一个防火墙之后,直接的 RMI 调用可能是您的最佳选择。在这种情形下,servlet 只会带来额外的开销和不必要的体系结构复杂性。在 applet 或 Java Web Start 情形中,通过提供带有 applet 或 Java Web Start 应用程序链接的首个 HTML 文档,servlet 可以启动事务。然后,最好使客户机与一个或多个会话 bean 建立直接的 RMI 连接。该方案的设置与典型的应用程序客户机方案(与服务器不在同一个防火墙之后)的设置相同。
如果您正在使用本机 GUI 客户机,并且需要管理复杂的事务或事务系列,那么您应该再次考虑调用 EJB 组件,就象它是 CORBA 组件一样。如果不能那样做,您可以始终让客户机通过 HTTP 与 servlet 通信,并且相应地管理会话。

Web 应用程序
在标准的、基于 Web 的应用程序情形中,客户机位于防火墙的哪一侧并不重要;使用 servlet 是必需的。因为您将使用 HTTP 作为传输协议,所以将在 Web 层上工作。唯一实际的决定 ? 是否在幕后使用 EJB 组件 ? 将取决于对 EJB 容器服务的相关需求。首先,您将选择通用的组件类型(如 servlet 和会话 bean)。接下来,您将选择一些匹配应用程序的用户界面显示和业务请求处理需求的更特定类型(如 JSP 页面和有状态会话 bean)。就所关心的状态管理而言,Web 应用程序中存在着和其它客户机类型中类似的问题。一些标准问题(和答案)将有助于您为您的 Web 应用程序确定合适的状态管理解决方案:

有状态体验需要直接与用户界面联系吗? 如果是,那么必须使用 servlet 和 HTTPSession API 管理状态。

您的业务过程需要跨越来自客户机的多个调用吗? 如果是,您有三种选项:
使用有状态会话 bean 来提供有状态业务过程。

使用无状态会话 bean,并且让持久数据高速缓存在服务器上。接着对高速缓存的引用可以存储在客户机的 HTTPSession 对象中。

通过调用 bean 上的方法使 JavaBean 充当业务委派(请参阅参考资料),从而使 bean 批处理所有来自客户机的数据,并且仅在客户机准备提交业务过程时才联系无状态会话 EJB 组件。再次使用了 HTTPSession API 来持久化 JavaBean 实例。

您的有状态业务过程需要故障保护吗? 如果是,您有三种选项:
使用应用程序服务器,该服务器为有状态会话 bean 的状态恢复提供自动支持。

SessionSycnhronization 接口允许无状态或有状态会话 bean 对事务故障做出响应。这将允许您回滚事务、持久化数据或执行您可能需要的任何其它清除功能。通常,服务器故障将不会阻碍容器调用由接口声明的回调方法。

许多 Web 服务器都提供了故障保护 HTTPSession 实现。如果您的服务器可以这样做,那么您可以使用 JavaBean 作为业务委派。

多客户机类型
最后的情形需要客户机类型的组合,例如基于 Web 的浏览器和标准的“富”GUI 桌面。在这种情形下,有状态选项同无状态选项没有区别。请参考本系列的第一篇文章以获取详细信息。

结束语
在本部分(J2EE Pathfinder 系列的第二部分)中,我们探讨了使用 Java servlet 和有状态会话 bean 来执行客户机请求和提供有状态体验的相对优缺点。本文讨论的方案并未包含所有情形,但是它们代表了有状态通信环境中的 servlet 和会话 EJB 组件的一些最常见用法。

在下一部分中,我们将开始有关持久数据管理的两部分探讨,首先将比较实体 bean 和 JDBC。愿我们到时“探索”愉快!


↑返回目录
前一篇: Aspectwerkz 2.0开发企业AOP快速入门
后一篇: 开发J2EE应用应遵循的几点原则