(1)
在用户进入表单页面的时候生成一个随机的数字,并赋值给一个session,并写入一个隐藏控件
在处理提交数据的页面判断传入的隐藏控件的值是否=session的值。
相等表明允许提交
最重要的一步:处理提交的数据成功后清空session,这样他反复提交过来的页面,隐藏控件的值是存在的,而session为空,就backup页面,告诉他,不能提交了
(2)
Struts的Token(令牌)机制能够很好的解决表单重复提交的问题,基本原理是:服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。
public
ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) // 前面的处理省略 saveToken(request); return mapping.findForward( " add " ); }在Action的insert方法中,我们根据表单中的Token值与服务器端的Token值比较,如下所示: public ActionForward insert(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) if (isTokenValid(request, true )) ... { // 表单不是重复提交 //这里是保存数据的代码 } else ... { //表单重复提交 saveToken(request); //其它的处理代码 } }
public
ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception ... { //这一句是输出调试信息,表示代码执行到这一段了 log.debug(":: action - subject add"); //your code here //这里保存Token值 saveToken(request); //跳转到add页面,在Structs-config.xml里面定义,例如,跳转到subjectAdd.jsp return mapping.findForward("add"); }
public
ActionForward insert(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) ... { if (isTokenValid(request, true)) ...{ // 表单不是重复提交 //这里是保存数据的代码 } else ...{ //表单重复提交 saveToken(request); //其它的处理代码 } }
public
abstract
class
BaseDispatchAction
extends
BaseAction
...
{
protected ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception ...{ String parameter = mapping.getParameter(); String name = request.getParameter(parameter); if (null == name) ...{ //如果没有指定 method ,则默认为 list name = "list"; } if ("add".equals(name)) ...{ if ("add".equals(name)) ...{ saveToken(request); } } else if ("insert".equals(name)) ...{ if (!isTokenValid(request, true)) ...{ resetToken(request); saveError(request, new ActionMessage("error.repeatSubmit")); log.error("重复提交!"); return mapping.findForward("error"); } } return dispatchMethod2(mapping, form, request, response, name); } } |