zoukankan      html  css  js  c++  java
  • 防止表单重复提交

    一、原理

    表单重复提交的三种情况:

    1.在表单没有到达目标页面前,对请求按钮点击n次。浏览器会将所有点击的请求排成一个队列,先进先出。

    2.在表单提交到达目标页面后,刷新目标页面。

    3.在表单提交后到达目标页面后,点击后退,再次提交。

    使用JS和重定向只能解决部分情况。

    使用token来解决:表单和Session域同时维护一个token唯一值。

    在加载页面的时候,同时向session域中和表单隐藏域中放入相同的token。

    <%
        String tokenStr = System.currentTimeMillis() + "-" + session.getId();
        session.setAttribute("token", tokenStr);
    %>
    <form action="/Session/SessionServlet" method="post">
        <input type="hidden" name="tokenParam" value="<%=tokenStr %>" />
        <input type="submit" value="submit">
    </form>

    到达目标方法后:

    判断表单提交的token值是否和session域中的值相等,若相等,则删除session域中的token值,到达目标页面。

    若重复提交,则在seesion域中找不到对应的token值,跳转到错误页面,给出提示。

    String tokenParam = req.getParameter("tokenParam");
    HttpSession session = req.getSession();
    Object token = session.getAttribute("token");
    if(tokenParam == null || !tokenParam.equals(token)) {
        System.out.println("重复提交!!");
        return ;
    }        
    session.removeAttribute("token");
    req.getRequestDispatcher("/target.jsp").forward(req, resp);

    二、Struts2

    (1)使用 <s:token/> 和 org.apache.struts2.interceptor.TokenInterceptor 或 org.apache.struts2.interceptor.TokenSessionStoreInterceptor 来进行防止表单重复提交。

    (2)<s:token/>

    在页面中使用 Struts2 标签 <s:token/>  会被解析为:

    <input type="hidden" name="struts.token.name" value="token">
    <input type="hidden" name="token" value="NUV93RXS5OQQVWL1Y1BTKHPPFK3L4UAX">

    (3)拦截器的配置

    默认拦截器栈 defaultStack,没有配置 org.apache.struts2.interceptor.TokenInterceptor 或是 org.apache.struts2.interceptor.TokenSessionStoreInterceptor。需要手动加入。

    <action name="token" class="com.nucsoft.struts.token.TokenAction">
        <interceptor-ref name="token"/>
        <interceptor-ref name="defaultStack"/>
        <result>/success.jsp</result>
        <result name="invalid.token">/form.jsp</result>
    </action>
    <action name="tokenSession" class="com.nucsoft.struts.token.TokenAction" method="tokenSession">
        <interceptor-ref name="tokenSession"/>
        <interceptor-ref name="defaultStack"/>
        <result>/success.jsp</result>
    </action>

    (4)org.apache.struts2.interceptor.TokenInterceptor org.apache.struts2.interceptor.TokenSessionStoreInterceptor 的区别

    TokenInterceptor :需要配置一个 name="invalid.token" 的一个 result,表单重复提交时,给出提示。提示信息会存放到 actionError 中,可以通过标签 s:actionerror 来获取信息。

    也可以在国际化资源文件中对信息实现定制(指定国际化资源文件基名):

    如:

    i18n_zh_CN.properties

    struts.messages.invalid.token=u8bf7u4e0du8981u91cdu590du63d0u4ea4u8868u5355(请不要重复提交表单)

    TokenSessionStoreInterceptor :不需要配置别的 result ,采取是一种静默模式,表单重复提交时,不会给出提示,但是实际上目标方法只会被执行一次。

    未写完,待续

  • 相关阅读:
    第一篇日志
    Spring mvc 4系列教程(三)—— Spring4.X的新特性
    Spring mvc 4系列教程(二)——依赖管理(Dependency Management)和命名规范(Naming Conventions)
    Spring mvc 4系列教程(一)
    【管理心得之三十六】《黄帝内经》中的一句话
    【管理心得之三十五】好习惯也能惹“骂名”
    【管理心得之三十四】“禅宗境界”的员工
    【管理心得之三十三】管理者的“眉头”
    【管理心得之三十二】PMP杂谈---------爱情必胜术
    【管理心得之三十一】我的位置
  • 原文地址:https://www.cnblogs.com/solverpeng/p/5633360.html
Copyright © 2011-2022 走看看