美文网首页
Struts 中的 Token 机制

Struts 中的 Token 机制

作者: 七弦桐语 | 来源:发表于2017-02-25 10:36 被阅读201次

背景

在提交表单的时候,通常有一种情况是新增加一条记录。当新增成功的时候,跳到添加成功的界面,如果用户点击了浏览器的回退,转到刚才的提交页面,再次点击提交。此时如果没有做处理,就会发生重复提交的问题。如果新插入一条记录不对重复提交进行处理的话,那么就会在数据库中重复插入同一记录,这样会在数据库产生冗余的重复记录。

Token 机制

Struts中的Token机制,实际上就是通过用户提交表单时,比较request中的请求参数org.apache.struts.taglib.html.TOKEN的值与当前会话中的属org.apache.struts.action.TOKEN的值是否相等,相等则是正常提交,不等则为重复提交。

 if (isTokenValid(request, true)) {
       // 未重复提交时,正确的时候应该做的事情
    return mapping.findForward("success");
} else {
    // 重复提交时,需要做的事情
    saveToken(request);
    return mapping.findForward("error");
} 

处理过程

1. 新增一条记录时

在转到新增界面的action中

public ActionForward add(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response) { 
  this.saveToken(request);//这个方法就是产生令牌值,struts已有的方法 
  return mapping.findForward("add");//返回新增页面
}

通过调用saveToken(request),产生一个token值。(注:每次调用saveToken方法产生的token值都不同)

然后在记录新增页面中的<html:form>内部增加一个隐含表单字段,形式如下:

<div>
  <input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="8b2d950f23b02c527988a14171254025">
</div>

然后再把token值8b2d950f23b02c527988a14171254025保存到当前会话中,也就是 session.setAttribute( "org.apache.struts.action.TOKEN","8b2d950f23b02c527988a14171254025");

2. 提交的数据保存

public ActionForward save(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response) { 
  if (this.isTokenValid(request)) {//正常提交
   //其它业务操作......
   this.resetToken(request);//清空当前会话中的token值
   return mapping.findForward("success");//返回保存成功页面
  } else {//重复提交   
   this.saveToken(request);//注:此方法在这里可要也可不要。  
   return mapping.findForward("fail");//返回重复提交提示信息页面
  }
}

判断是不是重复提交关键是isTokenValid(request)这个方法,这个方法由struts提供,如果返回结果为true则表示正常提交,false则为重复提交。isTokenValid(request)这个方法实际上主要做了三件事,

  1. 判断当前会话是否过期,如果过期,直接返回false
HttpSession session = request.getSession(false);
if (session == null) {
    return false;
}
  1. 然后再判断当前会话中是否存在令牌属性org.apache.struts.action.TOKEN,如果不存在,返回false
String saved =(String) session.getAttribute("org.apache.struts.action.TOKEN");
if (saved == null) {
    return false;
}

为什么令牌属性org.apache.struts.action.TOKEN会不存在呢,那是因为当用户正常提交后,会调用this.resetToken(request);//清空当前会话中的token值。也就是说resetToken(request)方法中调用了 session.removeAttribute("org.apache.struts.action.TOKEN");

3 .从当前会话中取得token的值与当前request中得到的token值比较,相同返回true,不同返回false

String token = request.getParameter("org.apache.struts.taglib.html.TOKEN");
if (token == null) {
    return false;
}
return saved.equals(token);

如果是重复刷新,那么每次request中的令牌值都是一样的,但每次刷新当前会话中的令牌值都被重新替换了,所以会返回false

:使用struts的表单提交Token机制时,提交的表单一定要写成<html:form></html:form>这种形式,如果写成<form></form>这种形式的话,尽管调用saveToken(request)方法也不会在当前的<form></form>里面生成隐含表单,最终的结果都是"重复提交".

相关文章

  • Struts 中的 Token 机制

    背景 在提交表单的时候,通常有一种情况是新增加一条记录。当新增成功的时候,跳到添加成功的界面,如果用户点击了浏览器...

  • struts2 token令牌机制介绍

    对于重复提交这一问题我们通常有两种解决方法: 通过重定向 通过session token 这里我们主要介绍sess...

  • 关于 中/与/*的区别

    前言:在框架的使用中,如果只没有使用spring框架 ,用到struts2框架时候,我们的struts2底层机制...

  • strust和springmvc,mybatis和hiberna

    struts和springmvc对比: 1.机制:spring mvc 的入口是 servlet,而 struts...

  • struts令牌token

    一.使用场景 (1)网络延迟的情况下,进行多次提交. (2)表单提交后用户点击【刷新】按钮导致表单重复提交 (3)...

  • refresh_token代码实现简图

    token 失效的 refresh_token 使用机制 axios 响应拦截器 的错误处理函数中,如果 响应状态...

  • 王兴武:致社区中评论扣token的学友

    关于token激励机制中你提到的评论扣token,这个我个人建议如下: 不但评论不是扣token,反而应该奖励to...

  • token 认证

    Token Auth的优点 Token机制相对于Cookie机制又有什么好处呢? 支持跨域访问: Cookie是不...

  • jsonwebtoken生成与解析token

    之前写了一篇介绍token的文章:简单理解Token机制,token算法自己设计的,使用了随机算法,导致token...

  • JWT

    概述 JWT 基于 token 的鉴权机制,基于 token 的鉴权机制类似于 http 协议也是无状态的,它不需...

网友评论

      本文标题:Struts 中的 Token 机制

      本文链接:https://www.haomeiwen.com/subject/hsbgwttx.html