在本文中,我们将紧随本系列的第二期“ 有状态网络的 J2EE 技术”。在那一期,您可以了解到 J2EE 中有状态应用程序开发的一些基础知识。这一次,我们将把注意力从大范围的概述转移到如何创建和管理有状态用户体验的细节上来。
创建有状态应用程序的一个基本组成部分就是数据管理。通过从一个会话全面地收集有关一个用户的数据,我们可以为那个用户创建一个简要表(profile),然后使用这个简要表来个性化他的用户体验。为了智能地管理用户数据,必须将其置于上下文中。出于这个原因,我们使用 作用域。
在 J2EE 中有 4 种作用域(或者说上下文)用于管理数据:application(应用程序)、session(会话)、request(请求)和page(页面)。在本月,您将学到每种作用域为 J2EE 中的有状态应用程序开发带来了哪些东西,以及每种作用域最适合于哪种会话管理场景。
首先我们来快速回顾一下 J2EE 中有状态 Web 应用程序的开发。
构建有状态 Web 应用程序
如果用户只需要用 Web 应用程序来查看静态内容,那么除了 HTML 外我们不需要任何其他的技术。但是,除了基于文本的信息和好看的背景颜色之外,大多数用户还想从 Web 那里得到更多的功能。实际上,目前多数的用户访问网络都是为了执行复杂的电子商务交易,参与在线社团,下载(和上传)媒体,等等。对于大多数流行站点来说,交互性是关键,而且,个性化的功能越多越好。对于这种类型的开发,我们使用一些高级的 Web 技术,例如 CGI、PHP、ASP、JSP 以及 Java Servlet。
交互性的一个重要的组成部分就是个性化。 个性化的 Web 站点能够针对用户的特定需求和兴趣来定制内容和输出。个性化的一个重要组成部分就是 duration。用户体验不仅应该具有内聚性,还应该加以扩展,超越单事务模式。例如,当登录到像 Yahoo 这样的一个个性化的门户时,您将建立一个 身份(identity),在 Yahoo 域中,无论导航到哪里,您的身份都不会改变。对于许多在线银行、信用卡以及股票交易系统来说,也是如此。在线商店也逐渐地采用了这种模型。
当我们谈到扩展了单事务模式的用户体验时,我们称之为 会话。当我们创建支持会话而不是单独的、孤立的事务的 Web 应用程序时,我们就是在创建 有状态的应用程序。
在一个有状态应用程序中,用户可以导航到站点的许多不同的地方,并执行多个事务,但是他将一直维护着他自己惟一的身份。这是可以实现的,因为系统会不断地跟踪他的会话的 状态。在 J2EE 中,这种类型的开发是通过将每个用户的信息存储在一个后端数据服务器上来进行管理的。当一个用户第一次登录到站点时,他便建立一个惟一的 ID。从那一刻开始,与该用户的 ID 相关的数据便被存储起来,并且在需要的时候系统可以访问这些数据。
至于 Java 平台,我们可以使用三种技术之一来将用户 ID 与单个用户关联起来,这三种技术是:URL 重写、隐藏表单字段以及 HTTP cookies。在 J2EE 中,我们使用 HTTPSession API 来存储、检索会话数据,或者将会话数据与某一特定用户 ID 相关联。
除了存储数据,我们还必须能够 contextualize数据(将数据置于上下文中)。术语 作用域 指的是被存储数据的上下文(即该数据的 “作用域”);对作用域的适当处理在有状态 Web 应用程序的设计中处于核心地位。
会话作用域
术语“作用域”指的是一个上下文,在这个上下文中数据被关联或者存储。在传统的独立应用程序中存在着一些可以在其中关联变量和对象引用的上下文(或作用域)。典型的作用域包括:
局部/方法
类/对象/组件
包/库
protected(受保护的)
全局/public(公共的)
在 Web 应用程序中所说的作用域不同于更传统的、独立的应用程序中所使用的作用域。在 Web 应用程序中,作用域指的是一个对象可以多大程度地为一个应用程序的组件所使用。而在独立应用程序中,虽然作用域所指的也是可用性,但这里的作用域是由代码块来划分界限的。
在 J2EE Web 应用程序中,一共有 4 种会话作用域:
page
request
session
application
每种 J2EE 作用域都有一个上下文,在这个上下文中可以关联(存储)基本类型的数据和对象引用,以供享有同一上下文的其他组件使用。表 1 列出了这 4 种作用域,并说明了它们是否能应用于 servlet 和 JSP 页面,还给出了对每种作用域的描述。
表 1. 4种会话作用域
会话作用域 Servlets JSP 页面 描述
page否是代表与一个页面相关的对象和属性。一个页面由一个编译好的 Java servlet 类(可以带有任何的 include 指令,但是没有 include 动作)表示。这既包括 servlet 又包括被编译成 servlet 的 JSP 页面
request是是代表与 Web 客户机发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个 Web 组件(由于 forward 指令和 include 动作的关系)
session是是代表与用于某个 Web 客户机的一个用户体验相关的对象和属性。一个 Web 会话可以也经常会跨越多个客户机请求
application是是代表与整个 Web 应用程序相关的对象和属性。这实质上是跨越整个 Web 应用程序,包括多个页面、请求和会话的一个全局作用域
接下来,我们将看看用于将数据存储在这 4 种作用域中的一些机制。
将数据存储在作用域中
在这 4 种作用域中,每一种作用域都有一个不同的机制,用于存储并最终访问上下文相关的数据。每种作用域都有一个单独的类,通过这个类可以存储和检索上下文相关的数据。表 2 标出了 4 个类,分别对应于 4 种会话作用域。
表 2. 用于存储有作用域的数据的类