zoukankan      html  css  js  c++  java
  • 12、Struts2表单重复提交

    1. 什么是表单重复提交

      • 表单的重复提交:
      • 若刷新表单页面, 再提交表单不算重复提交.
      • 在不刷新表单页面的前提下:
        • 多次点击提交按钮
        • 已经提交成功, 按 "回退" 之后, 再点击 "提交按钮".
        • 在控制器响应页面的形式为转发情况下,若已经提交成功, 然后点击 "刷新(F5)“
      • 重复提交的缺点:
        • 加重了服务器的负担
        • 可能导致错误操作.
      • token(令牌)
        1. 用户在访问页面时,我们要生成一个随机的token值
        2. 将该值放入到session域中,同时放在表单隐藏域中
        3. 用户提交请求时,隐藏域中token将会一起提交
        4. 服务器在处理请求时先要检查请求参数中的token和session中的token是否一致
          • 如果一致,则处理请求
          • 否则,返回错误页面
        5. 注意,token使用过一次以后必须要从session域中移除
    2. Struts2 解决表单重复提交

    1. 标记管理

      • Struts 提供的 token 标签可以用来生成一个独一无二的标记. 这个标签必须嵌套在 form 标签的内部使用, 它将在表单里插入一个隐藏字段并把标记值(隐藏域的字段的值)保存在HttpSession 对象里.
      • Token 标签必须与 Token 或 TokenSession 拦截器配合使用, 这两个拦截器都能对标记进行处理.
      • Token 拦截器在遇到重复提交情况时, 会返回 invalid.token 结果并加上一个 Action 错误. 这种错误默认的消息是: The form has already been processed or no token was supplied, please try again.
      • TokenSession 拦截器采取的做法只是阻断后续的提交, 用户将看到同样的响应,但实际上并没有重复提交
    2. Struts2 解决表单的重复提交问题:

      • 在 s:form 中添加 s:token 子标签

        • 生成一个隐藏域
        • 在 session 添加一个属性值
        • 隐藏域的值和 session 的属性值是一致的.
      • 使用 Token 或 TokenSession 拦截器.

        • 这两个拦截器均不在默认的拦截器栈中, 所以需要手工配置一下
        • 若使用 Token 拦截器, 则需要配置一个 token.valid 的 result
        • 若使用 TokenSession 拦截器, 则不需要配置任何其它的 result
      • Token VS TokenSession

        • 都是解决表单重复提交问题的
        • 使用 token 拦截器会转到 token.valid 这个 result
        • 使用 tokenSession 拦截器则还会响应那个目标页面, 但不会执行 tokenSession 的后续拦截器. 就像什么都没发生过一样!
      • 可以使用 s:actionerror 标签来显示重复提交的错误消息.

        • 该错误消息可以在国际化资源文件中覆盖. 该消息可以在 struts-messages.properties 文件中找到struts.messages.invalid.token=The form has already been processed or no token was supplied, please try again.
    <s:form action="testForm" >
        <!-- 增加token 标签,隐藏属性 -->
        <s:token></s:token>
    
        <s:textfield name="username" label="用户名"></s:textfield>
        <s:submit value="提交"></s:submit>
    </s:form>
    
    <!-- token 拦截器 -->
    <action name="testForm" class="org.pan.action.TestFormAction" method="testForm">
        <!-- 使用token 拦截器,进行表单重复提交校验 -->
        <interceptor-ref name="token"></interceptor-ref>
        <!-- 不要忘记默认的拦截器栈-->
        <interceptor-ref name="defaultStack"></interceptor-ref>
    
        <!-- 如果是使用的是 token 拦截器,校验失败后会转到 invalid.token -->
        <result name="invalid.token">/WEB-INF/views/token-error.jsp</result>
        <result name="success">/WEB-INF/views/success.jsp</result>
    </action>
    
    <action name="testForm" class="org.pan.action.TestFormAction" method="testForm">
       <!-- 使用tokenSession 拦截器,进行表单重复提交校验 -->
        <interceptor-ref name="tokenSession"></interceptor-ref>
        <!-- 不要忘记默认的拦截器栈-->
        <interceptor-ref name="defaultStack"></interceptor-ref>
    
        <!-- 如果是使用的是 tokenSession 拦截器,校验后会回到返回的 action方法 result。就像什么都没发生过 -->
        <result name="success">/WEB-INF/views/success.jsp</result>
    </action>
    
    人生如棋,我愿为为卒;行走虽慢,可曾见我后退一步!
  • 相关阅读:
    Redis
    Log4Net
    EF脚手架生成数据库上下文(scaffold-dbcontext)
    quartz.net
    基于LNMP的小米电子商务网站平台
    LVS的DR模式负载均衡
    华为交换机SSH配置
    VMware ESXi 6.5安装
    VLAN划分
    华为路由设备SSH配置
  • 原文地址:https://www.cnblogs.com/MPPC/p/6134207.html
Copyright © 2011-2022 走看看