struts解决重复提交问题(Token)

首先要在第一次进入到添加用户页面时要使用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" onsubmit="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值即可解决

你可能感兴趣的:(apache,html,struts)