首先要在第一次进入到添加用户页面时要使用toAddUser.do的url形式进入
在ToAddUserAction类中实现方法
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
... ...
saveToken(request);//在session中保存token值
... ...
return mapping.findForward("toAddUser");
}
在页面中要使用html:form标签,struts会在该标签的开始执行标签的代码中在form的表单项中加入一个名字为org.apache.struts.taglib.html.TOKEN的hidden类别的一个input值,查看页面的源代码可以看到
<form name="addUserForm" method="post" action="/DADJPT/addUser.do" οnsubmit="return validateForm();" target="_parent">
... ...
<input type="hidden" name="org.apache.struts.taglib.html.TOKEN"
value="45dd9d38ebd34db949842fbb7897f3f7">
... ...
</form>
这样的话在提交addUser.do的时候request会携带此变量
在addUserAction中可以判断request中的token值是否跟存放在session中的token一样,不一样得话则转到页面过期的界面,并重置token值,如果相同则执行insert表操作,并也重置token值,并重新回到添加界面
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
AddUserForm addUserForm = (AddUserForm)form;
User user = addUserForm.getUser();
if(idTokenValid(request,true)){
userDao.add(user);
... ...
}else{
saveToken(request);
return mapping.findForward("timeoutPage");
}
return mapping.findForward("toAddUser");
}
这样在按f5刷新后者回退后再提交form将不会进行重复提交
关于在文章开头提到的问题,经测试是因为在页面中使用了<iframe />标签,表单是放在frame标签中的,而提交成功后又回到了添加界面,回退后在外部页面中的org.apache.struts.taglib.html.TOKEN值保持原来的值不变(该值可以通过session.getAttribute("org.apache.struts.action.TOKEN")得到),而在iframe标签中的,在每一个提交成功的页面里面org.apache.struts.taglib.html.TOKEN值都已经刷新为新生成的token值了,所以可以进行有效得提交,在ifrme中body属性onload中加入document.forms[0].getElementsByTagName("input")[0].value = window.parent.document.getElementById("org.apache.struts.taglib.html.TOKEN1").value;并在外部页面中手动加入一个同名的hidden值即可解决
在ToAddUserAction类中实现方法
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
... ...
saveToken(request);//在session中保存token值
... ...
return mapping.findForward("toAddUser");
}
在页面中要使用html:form标签,struts会在该标签的开始执行标签的代码中在form的表单项中加入一个名字为org.apache.struts.taglib.html.TOKEN的hidden类别的一个input值,查看页面的源代码可以看到
<form name="addUserForm" method="post" action="/DADJPT/addUser.do" οnsubmit="return validateForm();" target="_parent">
... ...
<input type="hidden" name="org.apache.struts.taglib.html.TOKEN"
value="45dd9d38ebd34db949842fbb7897f3f7">
... ...
</form>
这样的话在提交addUser.do的时候request会携带此变量
在addUserAction中可以判断request中的token值是否跟存放在session中的token一样,不一样得话则转到页面过期的界面,并重置token值,如果相同则执行insert表操作,并也重置token值,并重新回到添加界面
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
AddUserForm addUserForm = (AddUserForm)form;
User user = addUserForm.getUser();
if(idTokenValid(request,true)){
userDao.add(user);
... ...
}else{
saveToken(request);
return mapping.findForward("timeoutPage");
}
return mapping.findForward("toAddUser");
}
这样在按f5刷新后者回退后再提交form将不会进行重复提交
关于在文章开头提到的问题,经测试是因为在页面中使用了<iframe />标签,表单是放在frame标签中的,而提交成功后又回到了添加界面,回退后在外部页面中的org.apache.struts.taglib.html.TOKEN值保持原来的值不变(该值可以通过session.getAttribute("org.apache.struts.action.TOKEN")得到),而在iframe标签中的,在每一个提交成功的页面里面org.apache.struts.taglib.html.TOKEN值都已经刷新为新生成的token值了,所以可以进行有效得提交,在ifrme中body属性onload中加入document.forms[0].getElementsByTagName("input")[0].value = window.parent.document.getElementById("org.apache.struts.taglib.html.TOKEN1").value;并在外部页面中手动加入一个同名的hidden值即可解决