isTokenValid防止表单重复提交

 

Struts中用isTokenValid(request,boolean)方法来防止刷新时表单重复提交!   Struts在你每次访问Action的时候,根据用户会话ID和当前系统时间对于每个会话生成一个唯一令牌,保存在你的Session里面,如果你在Action里的函数里面,使用了saveToken(request),那么这个令牌也会保存在这个Action所Forward到的jsp所生成的静态页面里。  如果你在你Action的方法里使用了isTokenValid,那么Struts将会从你的request里面去获取这个令牌值,然后和Session里的令牌值做比较,如果两者相等,就不是重复提交,如果不相等,就是重复提交了。

一、基本原理

服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,
看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给
客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次
提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。

二、首先介绍一下struts提供的有关令牌的相关方法

protected String generateToken(HttpServletRequest request) 创建一个令牌.
protected boolean isTokenValid(HttpServletRequest request) 检查令牌是否有效
protected boolean isTokenValid(HttpServletRequest request,Boolean reset) 检查令牌是否有效,并且重置令牌(如果reset 是true)
protected void resetToken(HttpServletRequest request) 重置令牌
protected void saveToken(HttpServletRequest request) 添加令牌

        //action生成令牌生成令牌方法

 protected String generateToken(HttpServletRequest request) {
       HttpSession session = request.getSession();
       try {
           byte id[] = session.getId().getBytes();
           byte now[] =
               new Long(System.currentTimeMillis()).toString().getBytes();
           MessageDigest md = MessageDigest.getInstance("MD5");
           md.update(id);
           md.update(now);
           return (toHex(md.digest()));
       } catch (IllegalStateException e) {
           return (null);
       } catch (NoSuchAlgorithmException e) {
           return (null);
       }
   }

三、参考样例

例如:在新增信息过程中增加防止表单重复提交(进入新增页面方法名称add(),保存信息方法名称save())。

1、add()中保存一个令牌令牌

在进入新增页面的方法add()中创建令牌,保存在你的session里面,这个Action方法add()所进入的jsp新增文件中将会根据session标识自动生成一个hidden(隐藏input属性)展示创建的令牌值。

//add()中的保存一个令牌代码

   saveToken(request);

//页面中生成的hidden代码:

<input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="c4b17c9f3795df7e0c7a8dc1c19d7a26">

2、save()中进行令牌比较

在save()方法中从request中取出第一步生成的hidden值,如果request中的令牌与session中令牌一致就说明不是重复提交表单。成功保存信息后的跳转页面将会保存一个新的令牌到session中,页面中hidden值也是新的令牌值。这时在跳转的页面中做刷新操作上一次请求的令牌与第二次请求的令牌值就会不一致,从而有效地防止了重复提交的发生。

注:如果程序是自动返回到新增页面就会重新执行add(),如跳转到其他页面比如说list(),那么list()也要同时加入saveToken(request);重新保存一个新的令牌

//save()中比较代码

if (isTokenValid(request, true)) {

     //表单不是重复提交 
            // 完成信息保存

     return mapping.findForward("success");
       } else {

     //表单重复提交 

     //其他操作
          return mapping.findForward("submitagain"); 
       }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值