借助ajax自动保存jsf表单

上传人:小** 文档编号:46162042 上传时间:2018-06-23 格式:DOC 页数:17 大小:171KB
返回 下载 相关 举报
借助ajax自动保存jsf表单_第1页
第1页 / 共17页
借助ajax自动保存jsf表单_第2页
第2页 / 共17页
借助ajax自动保存jsf表单_第3页
第3页 / 共17页
借助ajax自动保存jsf表单_第4页
第4页 / 共17页
借助ajax自动保存jsf表单_第5页
第5页 / 共17页
点击查看更多>>
资源描述

《借助ajax自动保存jsf表单》由会员分享,可在线阅读,更多相关《借助ajax自动保存jsf表单(17页珍藏版)》请在金锄头文库上搜索。

1、第 1 章 借助 Ajax 自动保存 JSF 表单: 第 2 部分在服务器端管理表单数据在服务器端管理表单数据级别: 中级Andrei Cioroianu, 高级 Java 开发人员和顾问, Devsphere2007 年 10 月 08 日在 “用 Ajax 自动保存 JSF 表单” 系列的第 1 部分中,作者兼 Java 开发人员 Andrei Cioroianu 为您展示了如何借助 Asynchronous JavaScript + XML(Ajax)和 JavaServer Faces(JSF)技术构建能自动保存 Web 表单的 Java 应用程序,介绍了如何用 JavaScript

2、和 XMLHttpRequest 获得、编码和提交表单数据,如何调整 JSF 请求生命周期来处理 Ajax 请求以及如何在服务器端从 JSF 组件树获取所提交的数据 。在这个包含三部分的系列文章的第 2 部分中,您将了解如何识别跨浏览器会话的匿名用户、如何为多个用户和页面管理自动保存的表单数据、如何选择数据存储库以及如何处理线程安全性问题。简介简介本系列的第 1 部分 中描述了这样一个场景:其中,应用程序在服务器上自动保存表单数据,在用户关闭或重新打开浏览器后,表单可以恢复。这个解决方案即使在用户浏览器失效或用户没有在 Web 表单上单击 Submit 就离开应用程序之后也可以很好地工作。本文

3、所附的示例应用程序(请参见 下载)包含了一个名为 SupportForm.jsp 的典型 JSF 表单,此表单的数据通过 AutoSaveScript.js 文件的 JavaScript 函数定期提交给服务器。SupportForm.jsp 和 AutoSaveScript.js 均在本系列 第 1 部分 做过介绍,该部分还展示了如何使用 JSF 阶段侦听器在不干扰应用程序逻辑的前提下处理 Ajax 请求。在本文中,您将学习如何构建线程安全的数据存储库来自动保存表单数据。您将看到如何选择数据结构、如何用用 JSF 组件树提取出的表单数据填充这些结构、如何恢复 JSF 组件的状态、如何限制数据存

4、储库的内存资源以及如何实现其持久性。您还会了解到几个 Web 技巧,例如如何使用过滤器和浏览器 ID cookies。跨会话识别用户跨会话识别用户要在用户关闭和重新打开浏览器之后恢复 Web 表单,应用程序要能跨会话识别用户,如果用户做过身份认证,这一点并不难实现。如果应用程序使用标准方法进行用户认证,就可以调用 getUserPrincipal() 方法,此方法在 HttpServletRequest 接口中定义,然后再用 java.security.Principal 的 getName() 方法获取用户名。如何应用程序支持匿名用户的表单保存和表单恢复特性,您也可以设置浏览器 ID,这个

5、ID 与会话 ID 十分类似,只不过后者是在单一的会话中跟踪用户。实际上,当用户首次访问应用程序时,可以取得会话 ID cookie 的值并设置另一个名为 BROWSERID 的 cookie。与会话开始生成、会话结束失效的会话 ID 不同,BROWSERID cookie 只设置一次,且可以在很长一段时间(比如几年)后才失效。使用使用 servlet 过滤器过滤器servlet 过滤器非常适合设置 BROWSERID cookie,因为当用户首次访问应用程序时,此过滤器可以截取每个 HTTP 请求,并将此 cookie 添加到 HTTP 响应。一旦浏览器通过第一个响应收到此 cookie,那

6、么所有后续响应都将包含 BROWSERID cookie,这样应用程序能够通过其浏览器 ID 来识别匿名用户。本文所附带的示例代码包含一个名为 BrowserIdFilter 的类,它实现了 javax.servlet.Filter。此类还有一个名为 getBrowserId() 的方法(参见 清单 1),它迭代请求对象的 cookie,返回 BROWSERID cookie 的值或 null(如果这样的 cookie 不存在)。清单清单 1. 获得浏览器获得浏览器 ID cookie文档选项文档选项打印本页打印本页将此页作为电子邮件将此页作为电子邮件发送发送未显示需要 JavaScript

7、的文档选项讨论讨论样例代码样例代码developerWorks Ajax 资源中心资源中心请访问 Ajax 资源中心,这里几乎囊括了关于 Ajax 编程模型的所有信息,包括各种文章和教程、论坛、博客、wikis、活动和新闻。用户会感谢您用户会感谢您本文接下来将会介绍在 Ajax 应用程序中构建自动保存功能如何能让用户的 Web 体验更加方便和高效。与此同时,您还可以获得几个高级的 Web 技巧,比如使用过滤器和用户浏览器 ID cookie。package autosave;.import javax.servlet.http.Cookie;.public class BrowserIdFil

8、ter implements Filter public static String BROWSERID = “BROWSERID“; / cookie namepublic static String getBrowserId(HttpServletRequest httpRequest) String browserId = null;Cookie cookies = httpRequest.getCookies();if (cookies != null)for (int i = 0; i .BrowserIdFilterautosave.BrowserIdFilterBrowserId

9、Filter/*.浏览器 ID 的解决方案只能用在表单不 包含任何敏感信息的情况下,原因是所有通过这个共享的计算机使用此应用程序的用户都会被视为同一个用户。 跨会话识别用户的惟一一种最安全的方案是使用基于用户名和密码的标准身份认证方法。但基于密码的身份认证要求用户必须登录到应用程序,这很不方便。在很多时候,安全性最为重要,但有时,与其注册到站点,用户更愿意保持匿名。浏览器 ID 提供了识别匿名用户的一种简便方式。本系列所给出的表单自动保存特性适用于认证的和匿名的这两类用户。在接下来的章节中,您将看到如何存储和检索自动保存的表单数据以及如何在多线程的环境中使用表单数据。设置浏览器设置浏览器 ID

10、浏览器 ID 也可以用于通过身份认证的用户以便他们无需每次访问应用程序时都要登录。您可能也见过这样的站点,其中的登录屏幕上有标着 “Remember me on this computer” 的复选框。这样的复选框就是让此站点能够设置浏览器 ID 以便用户不必在返回该站点时还要再次登录。选择数据存储库选择数据存储库首先,为了保存表单数据,必须选择数据结构和存储库。这一点十分重要,因为为了存储临时数据,经常需要访问存储库。在示例应用程序中,数据每隔 10 秒为每个表单实例自动保存一次,但在真正的应用程序中,如果具有大量的并发用户,可能将这个间隔提高到 10 分钟更为合理一些。自动保存的表单数据自

11、然要存储在内存中,原因是这些数据只会存储很短的一段时间,之后会被更新的数据所替代。在用户提交表单之前,每个表单实例都会定期保存数据。提交之后,任何与所提交表单相关的临时数据都会从内存清除。如果用户不能提交表单或没有单击提交按钮就放弃了此页面,那么最后保存的数据会尽可能久地被存储在内存。当用户再次返回此表单时,如果所保存的数据还在,他就可以选择恢复此表单。 保存和恢复保存和恢复 JSF 组件的值组件的值每个表单实例的自动保存数据都保存在 Map 实例中。这类数据地图的每个条目和元素都包含 JSF 输入组件的值,其 ID 是数据地图的键。这个结构与 javax.servlet.ServletReq

12、uest 的参数地图类似,但却不完全相同,原因是请求参数地图包含字符串数组,而存储库数据地图则保存 JSF 视图的所有输入组件的转变和验证后的值。DataMapRepository 类的 saveValues() 方法是一种递归方法,可以遍历 JSF 组件树,用能实现 EditableValueHolder 的输入组件的值填充数据地图(参见 清单 4)。清单清单 4. 将将 JSF 输入组件的值存储到数据地图输入组件的值存储到数据地图package autosave;.import ponent.EditableValueHolder;import ponent.UIComponent;.pu

13、blic class DataMapRepository . .public static void saveValues(UIComponent comp,Map dataMap) if (comp = null)return;if (comp instanceof EditableValueHolder) / Input component. Put its value into the data mapEditableValueHolder evh = (EditableValueHolder) comp;dataMap.put(comp.getId(), evh.getValue();

14、/ Iterate over the children of the current componentIterator children = comp.getChildren().iterator();while (children.hasNext() UIComponent child = (UIComponent) children.next();/ Recursive callsaveValues(child, dataMap);回页首回页首.restoreValues() 方法(如 清单 5 所示)遍历此 JSF 组件树,恢复输入组件的值。此方法还清除了每个 EditableValu

15、eHolder 组件的 submittedValue 属性以便表单数据能恢复成地图数据,同时忽略所有的提交数据。saveValues() 方法在本文稍后的部分会用到,restoreValues() 会在本系列的第 3 部分用到。清单清单 5. 恢复恢复 JSF 输入组件的值输入组件的值package autosave;.import ponent.EditableValueHolder;import ponent.UIComponent;.public class DataMapRepository . .public static void restoreValues(UIComponent

16、 comp,Map dataMap) if (comp = null | dataMap = null)return;if (comp instanceof EditableValueHolder) / Input component. Get its value from the data map/ and clear any submitted valueEditableValueHolder evh = (EditableValueHolder) comp;evh.setValue(dataMap.get(comp.getId();evh.setSubmittedValue(null);/ Iterate over the children of the current componentIterator children = comp.getChi

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 商业/管理/HR > 经营企划

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号