方法有二:
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) %>">