原理: 服务器端在处理客户端的请求之前,会将请求中包含的令牌值与保存在当前会话中的令牌值进行比较,看是否匹配。在处理完该请求后,并且在信息达到客户端之前,将产生一个新的令牌。该令牌值将会替换当前会话中的令牌值,并且传到客户端。这样如果用户回退到刚才的提交页面并再一次提交的话,客户端传过来的令牌与服务其中的令牌值不一致,从而有效的防止了提交
Struts本身有一套完善的防止重复提交表单的Token(令牌)机制,但笔者目前的项目自写的framework没有用到Struts,故也得自写防止用户因为后退或者刷新来重复提交表单内容的Token机制。不难,容易实现。
实现原理:一致性。jsp生成表单时,在表单中插入一个隐藏<input>字段,该字段就是保存在页面端的token字符串,同时把该字符串存入session中。等到用户提交表单时,会一并提交该隐藏的token字符串。在服务器端,查看下是否在session中含有与该token字符串相等的字符串。如果有,那么表明是第一次提交该表单,然后删除存放于session端的token字符串,再做正常业务逻辑流程;如果没有,那么表示该表单被重复提交,做非正常流程处理,可以警告提示也可以什么也不做。
看代码。
首先是Token主类。类很简单,而且主要方法都给doc注释了
import java.util.ArrayList;
import javax.servlet.http.HttpSession;
public class Token {
private static final String TOKEN_LIST_NAME = "tokenList";
public static final String TOKEN_STRING_NAME = "token";
private static ArrayList<String> getTokenList(HttpSession session) {
Object obj = session.getAttribute(TOKEN_LIST_NAME);
if (obj != null) {
return (ArrayList<String>) obj;
} else {
ArrayList<String> tokenList = new ArrayList<String>();
session.setAttribute(TOKEN_LIST_NAME, tokenList);
return tokenList;
}
}
private static void saveTokenString(String tokenStr, HttpSession session) {
ArrayList<String> tokenList = getTokenList(session);
tokenList.add(tokenStr);
session.setAttribute(TOKEN_LIST_NAME, tokenList);
}
private static String generateTokenString(){
return new Long(System.currentTimeMillis()).toString();
}
/**
* Generate a token string, and save the string in session, then return the token string.
*
* @param HttpSession
* session
* @return a token string used for enforcing a single request for a particular transaction.
*/
public static String getTokenString(HttpSession session) {
String tokenStr = generateTokenString();
saveTokenString(tokenStr, session);
return tokenStr;
}
/**
* check whether token string is valid. if session contains the token string, return true.
* otherwise, return false.
*
* @param String
* tokenStr
* @param HttpSession
* session
* @return true: session contains tokenStr; false: session is null or tokenStr is id not in session
*/
public static boolean isTokenStringValid(String tokenStr, HttpSession session) {
boolean valid = false;
if(session != null){
ArrayList<String> tokenList = getTokenList(session);
if (tokenList.contains(tokenStr)) {
valid = true;
tokenList.remove(tokenStr);
}
}
return valid;
}
}
怎么使用?
在jsp页面端。
首先import该类:
<%@ page import="com.paizuo.framework.util.Token" %>
表单包含隐藏的token字符串:
<form>
......
<input type="hidden" name="<%=Token.TOKEN_STRING_NAME %>" value="<%=Token.getTokenString(session) %>">
......
</form>
在Server端action中进行检验。
if(Token.isTokenStringValid(request.getParameter(Token.TOKEN_STRING_NAME), request.getSession())){
//进行正常业务流程
}
else{
//进行防重复提交处理流程
}
完毕。
相关推荐
struts2防止表单重复提交,利用struts的拦截器tokenSession,轻轻松松解决表单重复提交的问题。 附件为源代码,后台延迟了3秒,可直接在web服务器下部署运行,输入用户名和密码后,多点几次提交按钮,然后看控制台...
提供源代码和思想,整体架构都在,只需加入你自己的业务逻辑即可。
struts2_token控制刷新重复提交
JavaEE Struts2利用tokenSession防止重复提交
在struts 中可以通过token 来解决重复提交的问题。
自定义封装注解类,(生成token存放到redis中)通过注解的方式解决API接口幂等设计防止表单重复提交
struts token机制解决表单重复提交
struts2token回退刷新
详细介绍struts+token机制解决表单重复提交问题。附带相关代码
利用Token机制解决重复重复提交
用struts的token解决重复提交问题
Struts 之旅 - 重复提交 token
防止表单重复提交的方法(简单的token方式),内附实现代码及实现思路。
源码,下载下来直接可以用(防止用户刷新,重复提交数据) 有十分清晰的操作步骤,和注释,代码也封装的很好,我经常用
token-springMVC 防止重复提交
这里是Struts2 中放置表单重复提交的例子。
要解决这个问题,可以采用两种策略:一是自动刷新token,二是token续约。通过在验证用户权限的同时为用户生成新的token并返回给客户端,可以确保客户端及时更新本地存储的token。此外,设置定时任务来刷新token也是...
NULL 博文链接:https://minejava.iteye.com/blog/960617
token工具,集成了token校验和注解方式token放行策略,解压后直接将java文件放到项目中,引入一下maven就可以用了,亲测可用,如果有问题欢迎留言评论或者私信,可以帮忙解决问题
主要讲解了在structs怎样通过Token令牌解决表单重复提交的问题。附带了擦参考项目。