struts2 防止重复提交 实例代码

首先说说重复提交是怎么产生的,一般情况下有两种方式:  
      
    1,页面提交后再次刷新页面。  
      
    2,在提交的时候多次点击提交按钮。  

      
    strut1.x中解决防止提交1的方法是通过重定向解决,但是方式2在网速很慢或者是用户快速的点击提交按钮时,还是能够重复提交数据。  
      
    struts2中为方式2提供了解决方案(方式1用重定向是也可以防止用户刷新页面而引起的重复提交),struts2通过使用令牌(token)解决此类的问题。  
      

    要使用token,首先在页面上在你要提交的表单中加上<s:token/>,次标签解析后会生成两个隐藏域: 

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

    在该标签执行完成后会生成一个随机的值(红色部分),该值同时会加入到session中。  
     其次,就是在你个struts.xml中加入token拦截器。  
   

 <package name="token-struts" extends="struts-default">
    <interceptors>
    <interceptor name="token"/>
    <interceptor-stack name="token-default">
    <interceptor-ref name=" token "/>
    <interceptor-ref name="defaultStack"/>
    </interceptor-stack>
    </interceptors>
    <default-interceptor-ref name="token-default"/>
    </package>

 
    如果是用注解的话,那么的action要这么定义:@ParentPackage("token-struts")。  
    如果不是注解,可以将上面的拦截器栈加入到你的actin定义中。  
    这样就完成了整个防止重复提交的任务了。  
    如果你想了解此拦截器是这么工作的,你可以打开源码看看,其中TokenHelper.validToken()最是关键,就是通过这个帮助类完成对令牌的判断。  
      
    上述是可以解决重复提交的问题,但是随之而来的又是一个麻烦。  
    拦截器顾名思义就是用来对请求进行拦截的,一个请求在执行前就被拦截了,默认情况下拦截器会拦截被配置下所有的请求。但是很多情况下该配置下的其他请求不需要这个拦截,比如删除,更新操作。就完成不需要这个拦截器去拦截。拦截器又不能区分不同的请求而做出不同的操作。  
      
    这种情况就有两种解决方案:  
    第一,不用token拦截器,只在你需要防止重复提交的action处理方法中加入 TokenHelper.validToken()这个判断,如果为返回true就执行,否则跳过。  

    第二,用token拦截器,但是重写此拦截器TokenInterceptor。在重写的拦截器中判断tokenNames,如果值为空则不做任何操作,如果有值则做拦截。

1、使用Struts2的表单标签,其中需要增加token标签。index.jsp表单页面

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>

    <title>防止表单重复提交</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
  </head>

  <body>
      <!-- 防止表单重复提交,记得在form表单里填上<s:token></s:token>      -->
      <!-- action="token"、action="tokenSession" -->
      <s:form action="token.action" namespace="/test" method="post">
          姓名:<s:textfield name="name"/><s:token></s:token>
          <input type="submit" value="发送"/>
      </s:form>
  </body>
</html>

2.PersonAction类

package com.ljq.action;

import java.util.ArrayList;
import java.util.List;

public class PersonAction {

    private String name;

    @SuppressWarnings("unchecked")
    //观看控制台
    //如果token生效则不会在控制台输出name的值,而会输出如下警告: 2011-3-14 20:45:32 com.opensymphony.xwork2.util.logging.commons.CommonsLogger
    //warn 警告: Form token EDZ4S96RNDN5VD8B1CQTK6FTHIJUPC66 does not match the session token null.
    public String execute() {
        List ls = new ArrayList();
        ls.add(name);
        for (int i = 0; i < ls.size(); i++) {
            System.out.println(ls.get(i));
        }
        return "success";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

3.struts.xml配置文件

<?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">

<struts>
      <!-- 默认的视图主题 -->
    <constant name="struts.ui.theme" value="simple" />

    <!-- struts2在防止表单重复提交的拦截中有2个,分别是:token,tokenSession。tokenSession继承token而来。
          通常情况下,使用tokenSession客户端感觉会比较友好。 -->
    <!-- 如果重复提交,会跳转到error.jsp页面 -->
    <package name="person" namespace="/test" extends="struts-default">
        <action name="token" class="com.ljq.action.PersonAction">
            <interceptor-ref name="defaultStack" />
            <interceptor-ref name="token" />
            <!-- 如果重复提交,跳转到error.jsp页面 -->
            <result name="invalid.token">/WEB-INF/page/error.jsp</result>
            <result name="success">/WEB-INF/page/message.jsp</result>
        </action>
        <action name="tokenSession" class="com.ljq.action.PersonAction">
            <interceptor-ref name="defaultStack" />
            <interceptor-ref name="tokenSession" />
            <!-- 如果重复提交,不会跳转到error.jsp页面 -->
            <result name="invalid.token">/WEB-INF/page/error.jsp</result>
            <result name="success">/WEB-INF/page/message.jsp</result>
        </action>
    </package>
</struts>

4.message.jsp返回成功页面

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>

    <title>My JSP 'index.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
  </head>

  <body>
     <s:property value="name"/><br/>
     <%=new Date() %>
  </body>
</html>

5.error.jsp表单重复提交提示页面   

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP 'error.jsp' starting page</title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>

  <body>
      您已经提交了表单,请不要重复提交。
  </body>
</html>
时间: 2024-04-21 00:36:59

struts2 防止重复提交 实例代码的相关文章

token认证-struts2 token重复提交验证 跳转到错误页后如何返回

问题描述 struts2 token重复提交验证 跳转到错误页后如何返回 有一个用户身份认证的表单(页面A),用户输入个人信息后点击提交触发begin.action,认证通过后跳转到另外一个页面(页面B),为防止在此页面B上刷新操作在页面A中的begin.action上加入了token认证,如果出现重复提交会跳转到error.jsp的出错页面.问题:我想在error.jsp中加入一个"返回"链接 <a href="javascript:history.go(-1)&qu

五款java 删除数组元素与重复数组实例代码

五款java 删除数组元素与重复数组实例代码 本文章从网络上收藏了java 删除数组元素哦,各种删除数组元素都有自己的方法,这里不但可以删除数组元素而还可以删除重复的数组元素实例. package com.lzy; import java.util.hashset; import java.util.set; public class test {  /**   * @param args   */  public static void main(string[] args) {   // t

js防止表单重复提交实现代码_javascript技巧

基于令牌的处理就是一劳永逸的方法. 复制代码 代码如下: <script Language='JavaScript'> function formsubmit() { Today = new Date(); var NowHour = Today.getHours(); var NowMinute = Today.getMinutes(); var NowSecond = Today.getSeconds(); var mysec = (NowHour*3600)+(NowMinute*60)

防止表单重复提交实现代码

 代码如下 复制代码 <script Language='JavaScript'> function formsubmit() {     Today = new Date();     var NowHour = Today.getHours();     var NowMinute = Today.getMinutes();     var NowSecond = Today.getSeconds();     var mysec = (NowHour*3600)+(NowMinute*6

防止重复提交js代码

 代码如下 复制代码 <html xmlns="http://www.111cn.net/1999/xhtml"> <head runat="server"> <script type="text/网页特效"> var date = new array(); function disablebutton(button, validategroup) { date.push(new date()); if (da

通过JS在客户端限止用户重复提交的代码

程序介绍:1.方法一:hiddenForm 隐藏表单法: 查看函数 hiddenForm2.方法二:disButtons 禁用按钮法: 查看函数 disButtons disButtons23.本程序为客户端javascript程序限制多次提交,冰河原创首发蓝色理想,欢迎大家转载,但请保留本人信息,谢谢4.源码发布在我的手机主题站: http://www.qumiao.com/javascript/disRepSubmit.rar (本人所有原创程序均打包发在此)5.作者邮箱及QQ: bingh

Struts2 $,#,%详解及实例代码_java

最近在学ssh,一直搞不懂$,%,#的区别,做了点小练习,慢慢也懂了一点,将自己所学的也记录下来吧.    存在一下一个实体entity: public class Person { private int id ; private String Name ; public int getId() { return id; } public Person(int id, String name) { super(); this.id = id; Name = name; } public Per

用位图排序无重复数据集实例代码(C++版)_C 语言

<Programming Pearls>(编程珠玑下载)第一章讲述了如何用位图排序无重复的数据集,整个思想很简洁,今天实践了下. 一.主要思想 位图排序的思想就是在内存中申请一块连续的空间作为位图,初始时将位图的每一位都置为0,然后依次读取待排序文件的整数,将整数所在的位设置为1,最后扫描位图,如果某一位为1,则说明这个数存在,输出到已排序文件.比如待排序的数据S={3,0,4,1,7,2,5},max(S)=7,我们可以设置一个八位的位图B,将位图的每一位初始为0,即B=[0,0,0,0,0

jQuery 防止点击事件重复提交实例

定义全局标示符  代码如下 复制代码 //代码片段 var ddClick=false;  $(".cai").bind('click',function(){           if(ddClick){return;}           post_dig('cai');  });  $(".zan").bind('click',function(){           if(ddClick){return;}            post_dig('zan