收藏私塾在线
 

欢迎您来到私塾在线网!   

请登录! 

免费注册 


struts2的笔记
状态: 离线
人气:613681
访问用户量:855
笔记经验:
总积分:567
级别:普通会员
搜索本笔记
ta的交流分类
ta的交流主题贴(5)
ta的所有交流贴(5)
ta的全部笔记
全部笔记(89)
未分类笔记(3)
研磨struts2(86)
存档
2012-04(85)
2012-03(4)

2012-04-21 09:34:33
《研磨struts2》第十七章 防止重复提交 之 17.2 使用标签
浏览(6507)|评论(0)   交流分类:Java|笔记分类: 研磨struts2

17.2  使用<s:token/>标签

17.2.1  使用<s:token/>标签入门

Token也被称做令牌,所以使用<s:token/>标签防止重复提交,也常被称做使用令牌防止重复提交。

1:修改页面

       <s:token/>标签的使用非常简单,只需要在提交页面的<s:form>标签内加上子标签<s:token/>就可以了。

如果把提交页面当做重复提交时返回的结果页面的话,通常还需要在这个页面上引用重复提交时的错误信息。重复提交的错误信息以动作错误信息的方式存在,所以我们只要用<s:actionerror/>标签来引用即可。示例代码如下:

 

java代码:
<%@ page language="java" contentType="text/html; charset=gb2312"
    pageEncoding="gb2312"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Insert title here</title>
</head>
<body>
<%@ taglib prefix="s" uri="/struts-tags"%>
<s:actionerror/>
<hr>
<s:form action="/tokenAction.action" method="post">
	<s:token/>
	<s:textfield name="productId" label="预定的产品编号"/>
	<s:textfield name="orderNum" label="预定的数量"/>
	<s:submit value="提交"/>
</s:form>
</body>
</html>

2:修改struts.xml

使用<s:token/>标签,必须为Action引用名为token的预定义拦截器,它并不在defaultStack拦截器栈里,所以需要手动的引用token拦截器。

如果有重复提交的行为,Struts2将跳转到这个Action定义的名为invalid.token的Result,因此,需要修改struts.xml,示例代码如下:

 

java代码:
    <package name="helloworld" extends="struts-default">
        <action name="tokenAction" class="cn.javass.token.TokenAction">
        	<interceptor-ref name="token"/>
        	<interceptor-ref name="defaultStack"/>
        	<result>/token/list.jsp</result>
        	<result name="invalid.token">/token/add.jsp</result>
        </action>
    </package>

我们并没有修改TokenAction。那么,现在再次访问订单提交页面,且再次两次提交,可以看到页面跳转到invalid.token指定的Result,其实就是原来的提交页面,并输出重复提交的提示信息,如图所示:

图17.1 页面被重定向到指定的invalid.token结果

再看看控制台的输出,应该只有一次输出了,示例如下:

 

java代码:
预定的产品编号是:1,预定数量为:2
处理完成!

可以看到,重复的订单数据只被处理了一次,已经正确的处理了重复提交的问题。但是,还有一个小小的遗憾:页面停到了第二次提交被重定向到invalid.token结果上,而不能正确的走到第一次提交的success结果上。

17.2.2 <s:token/>的原理

为什么简简单单的引用<s:token/>标签,就能够实现防止重复提交的功能呢?

       下面来探究一下<s:token/>的运行原理,对于<s:token/>标签和token拦截器的两部分作用要分开来看:

  • <s:token/>标签在页面初始化的时候,向session中写入了一个名为struts.token的属性,其值是一个随机数;然后在表单中生成了两个隐藏域:struts.token.name域用来记录session中写入属性的名字,struts.token域记录了session的struts.token值一模一样的随机数。
  • token拦截器在请求提交的时候,在Action运行之前,比较session的struts.token属性和表单的struts.token隐藏域的值,如果这两个值相等,则移除session的struts.token属性,然后执行execute方法;如果不相等,则重定向到名为invalid.token的结果。

来把上面的两件事情画成流程图,估计比枯燥的文字更容易让人理解。如下图所示:

图16.2 使用令牌防止重复提交流程图

也许,有些朋友会说,既然struts.token隐藏域记录的值和session的struts.token属性记录的值一模一样,那么,在token拦截器运行的时候,比较的结果还可能不相等吗?

当然是可能的,因为token拦截器的作用在重复提交的时候才能显现出来。一起来分析分析,按照运行顺序,先后发生了如下的几件事情:

  • 首先,用户访问页面,这时候,<s:token/>标签要向session写入struts.token属性,假设这个随机数为123456789。那么,<s:token/>标签也同时要向<s:form/>写入名为struts.token的隐藏域,它的值也是123456789。
  • 然后,用户第一次提交这个页面,这时候,session中的struts.token属性和表单中的struts.token隐藏域的值都为123456789,判断为相等,所以token拦截器移除了session中的struts.token这个属性,整个防止重复提交的关键就在这步,然后继续运行execute方法,所以,这次提交是有效的。
  • 在第一次请求还没有运行完,用户再一次提交了这个页面。这时候,session中已经没有了struts.token属性,已经在第一次请求时被token拦截器移除了,但是表单中仍有struts.token隐藏域,所以二者肯定不相等了,那么,这次请求就被认为是重复请求,重定向到invalid.token指定的Result。

       补充说明:如果指定了<s:token/>标签的name属性,那么对session写入的属性名就不再是默认的struts.token,而是这个name值;同理对表单写入的隐藏域名也不再是默认的struts.token,也是这个name值了。在理解<s:token/>标签和token拦截器的作用时,基本不用理会struts.token.name隐藏域的作用。

 

私塾在线网站原创《研磨struts2》系列

转自请注明出处:【http://sishuok.com/forum/blogPost/list/0/4150.html

欢迎访问http://sishuok.com获取更多内容

精品视频课程推荐

Java数据结构和算法精讲版
本课程专注于数据结构和算法的内容,使用Java来进行代码示例,不空洞的讲解概念和理论,重点放在代码的实现和示例上。 从零开始、全面系统、成体系的讲解数据结构和基本算法,循序渐进的讲述构建软件系统所常见的数据结构和算法。

研磨设计模式——跟着cc学设计系列视频教程
本视频课程是北京Java私塾原创精品书籍《研磨设计模式》一书的配套学习视频,由《研磨设计模式》的第一作者CC录制 课程目标:全面、系统的掌握GoF设计模式的知识,达到可以在实际项目开发中运用的能力 技术要点:如何实现可配置、如何实现缓存以及缓存的管理、如何实现用缓存来控制多实例的创建、如何实现参数化工厂、 如何实现可扩展工厂、如何实现原型管理器、如何实现Java的静态代理和动态代理、如何实现多线程处理队列请求、 如何实现命令的参数化配置、可撤销的操作、宏命令、队列请求和日志请求、如何实现翻页迭代、如何检测环状结构、 如何实现通用的增删改查、如何模拟工作流来处理流程、如何实现简单又通用的XML读取、如何实现模拟AOP的功能......

struts2结合jFreeChat视频教程
深入浅出的讲解Struts2结合JFreechart来展示图表的功能

struts2防重复提交视频教程
深入浅出的讲解在Struts2开发中,如何防止页面的重复提交

深入浅出学Spring Web MVC视频教程
系统、完整的学习Spring Web MVC开发的知识。包括:Spring Web MVC入门;理解DispatcherServlet;注解式控制器开发详解;数据类型转换;数据格式化;数据验证; 拦截器;对Ajax的支持;文件上传下载;表单标签等内容;最后以一个综合的CRUD带翻页的应用示例来综合所学的知识

浏览(6507)|评论(0)   交流分类:Java|笔记分类: 研磨struts2

评论(0)
请登录后评论 登录

关于我们 | 联系我们 | 用户协议 | 私塾在线服务协议 | 版权声明 | 隐私保护

版权所有 Copyright(C)2009-2012 私塾在线学习网