Struts有一种防止表单被重复提交的机制。如果用户接二连三地单击表单的提交按钮,重复提交就会发生。通常,Struts会将这种情况处 理为两个单独的提交。当然这是一个错误。对这个问题的标准解决方案是使用一个事务令牌。
必须使用两个Action子类,第一个Action子类在表单被请求的时候被激活。它将在请 求和会话中放置一个唯一的字符串。这个唯一的字符串就是事务令牌。Action具有函数
saveToken(httpservletrequest,request)
来为你做这件事情。这个函数自动地产生事务令牌并且将其以适当的关键字放置在请求和会话中。 这个Action子类的execute()函数的一个简单的例子如下:
public class SaveToken extends Action {
/**//* forward name="usermesg" path="/usermesg.jsp" */
private final static String USERMESG = "usermesg";
// private final static String ERROR = "error";
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 在session中放入同步令牌
saveToken(request);
// example:
// return mapping.findForward(USERMESG);
return mapping.findForward(USERMESG);
}
}
第二个Action子类是在表单数据被用户提交时处理表单数据一次的动作。它的 execute()如下:
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 验证同步令牌
if (isTokenValid(request, true)) {//
return mapping.findForward(WELCOME);
} else {
return mapping.findForward(ERROR);
}
// TODO process request and return an ActionForward instance, for example:
// return mapping.findForward("forward_name");
}
}
函数isTokenValid(request,true)会进行检查,以确保在该请求上的 事务令牌与在会话中的令牌相匹配。一旦该检查完成,它便销毁该令牌在会话上的副本。这意味着如果用户第二次单击该提交按钮,在会话上将没有副本,导致 isTokenValid()返回false。