Struts2中防止表单重复提交的两种方式

    xiaoxiao2021-03-25  27

    防止表单重复提交,这是个很重要的知识点,而且很有用。当用户提交了一个表单,此时,地址栏显示的是处理这个表单的Action的地址,若此时刷新,则会重新发送一次表单数据,即又进行了一次提交,若这个Action是用来处理用户注册的,那么重复提交会再一次向数据库中插入之前已经插入的数据,这显然不是我们想要的。有两种方法,可以防止表单重复提交,一种是用Action的重定向,一种是用Session Token(Session令牌)。

    第一种方法,Action处理完用户提交的数据后,重定向到另一个Action或是一个页面,使用户提交后,所停留的位置,不是当前处理数据的Action,这样用户再刷新时,就不会再次执行这个Action了,就会避免表单重复提交的问题了。

    第二种方法,是一种很经典的处理这个问题的机制。这种方法是在用户要提交的表单中,加入一个<s:token>标签,这样,当浏览器第一次访问这个带有<s:token>标签的页面时,在服务器中,解析<s:token>标签的类(TokenTag.class),会生成一个随机的字符串(这个字符串,查看网页的源代码可以看到),并且发送给客户端的浏览器,同时,在服务器中,会把这个随机字符串保存到用户的session对象中。当第一次提交表单时,在服务器中,会比较客户端和服务器中分别保存的这个随机字符串,因为是第一次提交,所以这两个字符串相等,然后进行正常的业务处理。第一次提交后,在服务器中的session中保存的这个随机字符串,会改变为其他的随机值,注意,这是很重要的一步!此时,地址栏停留在处理用户提交数据的Action中,客户端中保存的随机字符串没有改变,若是刷新页面,即重复提交,服务器再进行两个字符串的比较,会不相等,就会跳转到name为invalid.token的结果页面中,这样就会防止表单重复提交了。

    第一种方法的举例,在上一篇博客中,这里就不再列出了,这里主要举例说明一下session token的机制:

    [html]  view plain  copy Login.jsp:      <s:form action="/test/token" theme="simple">           username:<s:textfield name="username"></s:textfield><br>           password:<s:password name="password"></s:password><br>           <s:submit value="submit"></s:submit>           <s:token></s:token><!--一定要有这个标签-->       </s:form>   [html]  view plain  copy struts.xml:      <action name="token" class="com.suo.actions.TokenAction">               <result name="success">/WEB-INF/result/LoginResult.jsp</result>               <result name="invalid.token">/WEB-INF/result/TokenFailed.jsp</result>               <!-- 若重复提交,则会跳转到这个页面,注意这里result的名字,一定要是invalid.token -->                              <interceptor-ref name="token"></interceptor-ref>               <interceptor-ref name="defaultStack"></interceptor-ref>               <!-- 这里一定要有这两个拦截器 -->           </action>   [java]  view plain  copy TokenAction.java:      package com.suo.actions;      import java.util.Map;      import javax.servlet.http.HttpServletRequest;   import javax.servlet.http.HttpSession;      import org.apache.struts2.ServletActionContext;      import com.opensymphony.xwork2.ActionContext;   import com.opensymphony.xwork2.ActionSupport;      public class TokenAction extends ActionSupport {       private String username;       private String password;              public String getUsername() {           return username;       }       public void setUsername(String username) {           this.username = username;       }       public String getPassword() {           return password;       }       public void setPassword(String password) {           this.password = password;       }              public String execute()       {              return SUCCESS;       }   }  

    结果页面就不写了

    原博文地址:http://blog.csdn.NET/hackerain/article/details/6990121

    PS:

    Struts2 解决表单的重复提交问题:(两种方式:①Action的重定向②如下) I. 在 s:form 中添加 s:token 子标签 > 生成一个隐藏域 > 在 session 添加一个属性值 > 隐藏域的值和 session 的属性值是一致的.  II. 使用 Token 或 TokenSession 拦截器.  > 这两个拦截器均不在默认的拦截器栈中, 所以需要手工配置一下 > 若使用 Token 拦截器, 则需要配置一个 token.valid 的 result > 若使用 TokenSession 拦截器, 则不需要配置任何其它的 result III. Token VS TokenSession > 都是解决表单重复提交问题的 > 使用 token 拦截器会转到 token.valid 这个 result > 使用 tokenSession 拦截器则还会响应那个目标页面, 但不会执行 tokenSession 的后续拦截器. 就像什么都没发生过一样! IV. 可以使用 s:actionerror 标签来显示重复提交的错误消息.  该错误消息可以在国际化资源文件中覆盖. 该消息可以在 struts-messages.properties 文件中找到 struts.messages.invalid.token=The form has already been processed or no token was supplied, please try again.

    转载请注明原文地址: https://ju.6miu.com/read-150148.html

    最新回复(0)