Struts 2防止表单重复提交

来源:互联网 发布:ubuntu重启网络命令 编辑:程序博客网 时间:2024/04/30 11:11
 设置Struts 2的预防表单重复提交的功能
  Struts 2已经内置了能够防止用户重复提交同一个HTML表单的功能。它的工作原理:让服务器生成一个唯一标记,并在服务器和表单里各保存一份这个标记的副本。此后,在用户提交表单的时候,表单里的标记将随着其他请求参数一起发送到服务器,服务器将对他收到的标记和它留存的标记进行比较。如果两者匹配,这次提交的表单被认为是有效的,服务器将对之做出必要的处理并重新设置一个新标记。随后,提交相同的表单就会失败,因为服务器上的标记已经重置。
  Struts 2标签中的token标签,可以用来生成一个独一无二的标记。这个标记必须嵌套在form标签中使用,它会在表单里插入一个隐藏字段并把标记保存到HttpSession对象里。toke标签必须与Token或Token Session拦截器配合使用,两个拦截器都能对token标签进行处理。Token拦截器遇到重复提交表单的情况,会返回一个"invalid.token"结果并加上一个动作级别的错误。Token Session拦截器扩展了Token拦截器并提供了一种更复杂的服务,它采取的做法与Token拦截器不同,它只是阻断了后续的提交,这样用户不提交多少次,就好像只是提交了一次。
  示例:使用Token拦截器预防表单重复提交
  配置struts.xml文件,声明动作
[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"    "http://struts.apache.org/dtds/struts-2.0.dtd">  
  2.   
  3.    <struts>  
  4.   
  5.    <package name="avoidPackage" extends="struts-default">  
  6.   
  7.    <action name="avoid" class="struts2.action.AvoidAction">  
  8.   
  9.    <interceptor-ref name="token"></interceptor-ref>  
  10.   
  11.    <interceptor-ref name="defaultStack"></interceptor-ref>  
  12.   
  13.    <result name="invalid.token">/error.jsp</result>  
  14.   
  15.    <result name="input">/input.jsp</result>  
  16.   
  17.    <result name="success">/output.jsp</result>  
  18.   
  19.    </action>  
  20.   
  21.    </package>  
  22.   
  23.    </struts>  
    此时,需要在动作的声明中,为动作添加token拦截器,因为token拦截器不在defaultStack拦截器栈中,注意,需要将拦截器放在拦截器栈的第一位,这是因为判断表单是否被重复提交的逻辑应该在表单处理前。
    创建动作类
[java] view plaincopy
  1. public class AvoidAction extends ActionSupport {  
  2.   
  3.    private static final long serialVersionUID = 2676453800249807631L;  
  4.   
  5.    private String username;  
  6.   
  7.    private Date birthday;  
  8.   
  9.    public String getUsername() {  
  10.   
  11.    return username;  
  12.   
  13.    }  
  14.   
  15.    public void setUsername(String username) {  
  16.   
  17.    this.username = username;  
  18.   
  19.    }  
  20.   
  21.    public Date getBirthday() {  
  22.   
  23.    return birthday;  
  24.   
  25.    }  
  26.   
  27.    public void setBirthday(Date birthday) {  
  28.   
  29.    this.birthday = birthday;  
  30.   
  31.    }  
  32.   
  33.    @Override  
  34.   
  35.    public String execute()  
  36.   
  37.    {  
  38.   
  39.    try {  
  40.   
  41.    Thread.sleep(4000);  
  42.   
  43.    } catch (InterruptedException e) {  
  44.   
  45.    e.printStackTrace();  
  46.   
  47.    }  
  48.   
  49.    return SUCCESS;  
  50.   
  51.    }  
  52.   
  53.    }  
    这个动作逻辑处理为挂起4秒钟,让我们有机会多次点击提交按钮,测试效果。
   创建页面:
    input.jsp
[html] view plaincopy
  1. <s:form action="avoid">  
  2.   
  3.     <s:token>  
  4.   
  5.     </s:token>  
  6.   
  7.     <s:textfield name="username" label="Enter your name"></s:textfield>  
  8.   
  9.     <s:textfield name="birthday" label="Enter your birthday"></s:textfield>  
  10.   
  11.     <s:submit value="submit">  
  12.   
  13.     </s:submit>  
  14.   
  15.     </s:form>  
    要使用Struts 2的防止表单重复提交功能,需要在form标签中使用token标签,他会产生一个唯一的标识符,与其他参数一起提交到服务器,服务器会根据token标签所产生的标识符判断表单是否为重复提交的表单,这个功能是由Token拦截器完成的。
    error.jsp
    <body>
    do not duplicate submissions form!
    </body>
    当表单重复提交,Token拦截器会返回一个"invalid.token"结果,结果将页面转到这个页面,提示用户错误信息。
    output.jsp
    <body>
    Your Name :<s:property value="username"/>
    <br />
    Your Birthday : <s:property value="birthday"/>
    </body>
    若没有重复提交表单,那么就显示正确的页面。
    测试
    在浏览器中输入:http://localhost:8081/AvoidDuplicateSubmissions/input.jsp,得到如下界面
    连续多次点击"submit"按钮,查看效果
    可以看到,token拦截器的设置生效了,他阻止了表单的重复提交,并给出了错误提示
    这次我们只点击一次提交(请重新输入URL,或后退到输入页面后刷新一下,这是因为token的标示在提交一次后已被修改,不刷新标示符是不可能与服务器存留的标示符一致的)
    可以看到,表单被正确的处理了。
    处理表单重复提交的另一个拦截器是 tokenSession,使用该拦截器与使用token拦截器并没有什么差异只需要,引用该拦截器,其他与token拦截器完全一致
[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2.   
  3.     <!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"    "http://struts.apache.org/dtds/struts-2.0.dtd">  
  4.   
  5.     <struts>  
  6.   
  7.     <package name="avoidPackage" extends="struts-default">  
  8.   
  9.     <action name="avoid" class="struts2.action.AvoidAction">  
  10.   
  11.     <interceptor-ref name="tokenSession"></interceptor-ref>  
  12.   
  13.     <interceptor-ref name="defaultStack"></interceptor-ref>  
  14.   
  15.     <result name="invalid.token">/error.jsp</result>  
  16.   
  17.     <result name="input">/input.jsp</result>  
  18.   
  19.     <result name="success">/output.jsp</result>  
  20.   
  21.     </action>  
  22.   
  23.     </package>  
  24.   
  25.     </struts>  
0 0
原创粉丝点击