表单提交, 应该是每个网页都会存在的一个内容。比如填写用户信息,填写个人资料。
向后台传送数据。那么可能就会有一些捣乱的用户,或者恶意工具服务器的
他可能多次点击提交按钮。导致服务器需要解析多次请求
那么就会出现问题。增加服务器压力。
解决方案1:
通过js ,定义一个全局变量。默认是false,当用户点击提交按钮。把全局变量该为true.
当用户点击第二次提交,会如果是true就不再执行提交。
代码如下
<script type="text/JAVAscript">
var isCommitted = false;//表单是否已经提交标识,默认为false
function dosubmit(){
if(isCommitted==false){
isCommitted = true;//提交表单后,将表单是否已经提交标识设置为true
return true;//返回true让表单正常提交
} else {
layer.msg("您已经提交过了,信息正在查询请您耐心等待..")
return false;//返回false那么表单将不提交
}
}
</script>
其次需要在表单onsubmit="return dosubmit()"
用户点击提交之后默认转到该方法下执行代码
以上一种解决方案,只能解决不懂技术的,小白用户 但是不能从根本上解决问题
还有一种方式 就是 在服务器做验证。这也是最佳的解决方案 (推荐使用这种方式)
这种解决方案简单概括就是:
用户点击跳珠表单页面,会默认生成一个token值。token值可以是uuid+算法生成的唯一值。方式多种多样都可以
然后把这个token值放入session中,后台可以通过el表达式把通过key拿出token值,存入form表单中的hidden隐藏表单中
用户每次提交,连同表单数据和这个token值发送到服务器。服务器去校验这个token值。
首先校验这个token值你要知道有几种情况
第一种:
表单中没有token,代表他重复叫
第二种
当前session中没有token,则用户代表重复提交
第三种
存储在session中的token令牌与表单Token不同,则代表用户重复提交
每种情况都要考虑进去,
直接干代码!!不说废话了
上面几种情况 我会单独 写出一个工具类
/**
* 判断客户端提交上来的令牌和服务器端生成的令牌是否一致
* @param args
* true:表示重复提交
* false:表示没有重复提交
*/
public static boolean isRepeatSubmit(HttpServletRequest request) {
String client_token = request.getParameter("token");
//第一种情况,如果提交表单没有token则该用户是重复提交表单
if (client_token == null){
return true;
}
//取出来存储在session中的令牌
String server_token = (String) request.getSession().getAttribute("token");
//2、如果当前用户的Session中不存在Token(令牌),则用户是重复提交了表单
if (server_token == null){
return true;
}
//3、存储在Session中的Token(令牌)与表单提交的Token(令牌)不同,则用户是重复提交了表单
if (!client_token.equals(server_token)){
return true;
}
return false;
}
2 跳转页面生产token值
//该方法主要用于跳转JSP页面,并且防止多次提交创建token
@RequestMApping(value = "findLogisticsPrice")
public String findLogistics(HttpServletRequest request, HttpServletResponse response){
String token = TokenUtils.getAccessToken(UUID.randomUUID().toString());
request.getSession().setAttribute("token", token);
return "modules/logisticsproviders/freightEstimateIndex";
}
生成token值的代码为:
/**
* 描述:生成Token方法
* @return
*/
public static String getAccessToken(String uuid){
String key = "UZ";
String timestamp = String.valueOf(System.currentTimeMillis());
return HmacSHA256((uuid+timestamp).getBytes(),key.getBytes());
}
3 在业务层直接处理逻辑
//判断用户是否是重复提交
boolean b = TokenUtils.isRepeatSubmit(request);
if (b==true){
String ze = "请不要重复提交!!!";
return ze;
}
当业务层逻辑快执行完时候
//移除session中的token
request.getSession().removeAttribute("token");