第一步:假如我们打开新增记录这个操作由add方法完成,代码如下:
public ActionForward add(ActionMapping mapping, ActionForm form,
}
通过调用saveToken(request),产生一个token值。(注:每次调用saveToken方法产生的token值都不同)然后在记录新增页面中的<html:form>内部增加一个隐含表单字段,形式如下:
<div>
<input type="hidden" name="org.apache.struts.taglib.html.TOKEN"
value="8b2d950f23b02c527988a141
</div>
然后再把token值"8b2d950f23b02c527988a141
第二步:假如我们提交这个页面数据由save方法完成,代码如下:
public ActionForward save(ActionMapping mapping, ActionForm form,
}
判断是不是重复提交关键是isTokenValid(request)这个方法,这个方法由struts提供,如果返回结果为true则表示正常提交,false则为重复提交。isTokenValid(request)这个方法实际上主要做了三件事,
1.判断当前会话是否过期,如果过期,直接返回false
2.然后再判断当前会话中是否存在令牌属性"org.apache.struts.action.TOKEN",如果不存在,返回false
为什么令牌属性"org.apache.struts.action.TOKEN"会不存在呢,那是因为当用户正常提交后,会调用this.resetToken(request);//清空当前会话中的token值。也就是说resetToken(request)方法中调用了 session.removeAttribute("org.apache.struts.action.TOKEN");
当用户重复提交时,我说了"this.saveToken(request);//此方法在这里可要也可不要。",下面我们分
析下,如果不调用这个方法,会话中就不会再重新保存token值,那么再刷新的时候,session中的token
值总是为null,isTokenValid(request)直接返回false,如果调用this.saveToken(request)的话,
session中会重新添加token属性值。这个时候isTokenValid(request)会进行下面第三步的判断。
3.从当前会话中取得token的值与当前request中得到的token值比较,相同返回true,不同返回false
/*重复刷新request令牌一样?还是重复点击提交时,requeset的令牌一样。转载注释*/
如果是重复刷新,那么每次request中的令牌值都是一样的,但每次刷新当前会话中的令牌值都被重新替换了,所以会返回false
注:使用struts的表单提交Token机制时,提交的表单一定要写成<html:form></html:form>这种形式,如果写成<form></form>这种形式的话,尽管调用saveToken(request)方法也不会在当前的<form></form>里面生成隐含表单,最终的结果都是"重复提交".