解决web页面刷新重复提交action导致插入重复数据的问题

方法有二:

1、action处理完用户提交的数据后,重定向到另一个action或者页面中,提交之后,所停留的位置不是当前处理数据的action了,再刷新也是无法插入数据。

struts.xml:
<action name="action1" class="com.suo.actions.Action1">
	 <result name="success" type="redictAction"><!--type指定是请求转发还是重定向-->
	 	<param name="actionName">action2</param><!--在这里指定要请求转发或是重定向到的Action-->
	 </result>
</action>
	 	
<action name="action2" class="com.suo.actions.Action2">
	<result name="success">XXX.jsp</result>
</action>

2、Session Token机制

在struct2中有这样的标签<s:token>,作用就是服务器通过token标签来产生盾牌随机数。当你第一次提交form的时候,解析<s:token>标签的类(TokenTag.class),会生成一个随机的字符串,且这个随机字符串可以右键查看网页源码可以看到。解析后存到客户端的浏览器,同时在服务器,保存到用户的session对象中。第一次提交表单,在服务器会比较这两个字符串,处理完业务之后,session保存的随机字符串会刷新,当你再刷新页面的时候,没有提交,即token产生的字符串没有改变,提交到服务器后,两个字符串不匹配就会跳转到name为invalid.token的结果页面中,这样就会防止表单重复提交了。

三步走实现防止表单重复提交

①jsp中的form里添加隐藏

 <%@ taglib prefix="s" uri="/struts-tags"%><!--引入标签头->
<s:form action="/test/token" theme="simple">
    	<!--你想封装的数据-->
    	<s:submit value="submit"></s:submit>
    	<s:token></s:token><!--重点在这-->
</s:form>

②action

正常处理即可

③struct.xml


<action name="token" class="com.suo.actions.TokenAction">
	 <result name="success">XXX.jsp</result>
	 <result name="invalid.token">XXXXX.jsp</result>
	 <!-- 若重复提交,需要跳转到特定的页面,需要注意这里result的名字,一定要是invalid.token -->
	 		
	 <interceptor-ref name="token"></interceptor-ref>
	 <interceptor-ref name="defaultStack"></interceptor-ref>
	 <!-- 默认的拦截器并没有包含token    因此需要加入 -->
</action>

2.1自己写,不利用struct的标签


//工具类
public class Token {
	   private static final String TOKEN_LIST_NAME = "tokenList";

	    public static final String TOKEN_STRING_NAME = "token";

	     private static ArrayList getTokenList(HttpSession session) {
	       Object obj = session.getAttribute(TOKEN_LIST_NAME);
	        if (obj != null) {
	          return (ArrayList) obj;
	        } else {
	          ArrayList tokenList = new ArrayList();
	          session.setAttribute(TOKEN_LIST_NAME, tokenList);
	          return tokenList;
	        }
	     }

	     private static void saveTokenString(String tokenStr, HttpSession session) {
	       ArrayList tokenList = getTokenList(session);
	       tokenList.add(tokenStr);
	       session.setAttribute(TOKEN_LIST_NAME, tokenList);
	     }
	   
	     private static String generateTokenString(){
	       return new Long(System.currentTimeMillis()).toString();
	     }

	     
	     public static String getTokenString(HttpSession session) {
	       String tokenStr = generateTokenString();
	       saveTokenString(tokenStr, session);
	       return tokenStr;
	     }

	     
	     public static boolean isTokenStringValid(String tokenStr, HttpSession session) {
	       boolean valid = false;
	        if(session != null){
	          ArrayList tokenList = getTokenList(session);
	           if (tokenList.contains(tokenStr)) {
	             valid = true;
	             tokenList.remove(tokenStr);
	           }
	        }
	       return valid;
	     }
}

action类,直接将if涵盖你的实现方法,else为重复提交的时候的操作
//判断
HttpServletRequest request = ServletActionContext.getRequest();
if(Token.isTokenStringValid(request.getParameter(Token.TOKEN_STRING_NAME), request.getSession())){


}

//JSP
<%@ page import="cn.wyu.timebank.utils.Token" %>
……
	<input type="hidden" name="<%=Token.TOKEN_STRING_NAME %>" value="<%=Token.getTokenString(session) %>">

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值