页面表单提交出现了重复提交的bug,在网络不好的时候,多次点击提交按钮,会出现多条一样的数据。
之前以为是由于表单提交导致的这个bug,于是改写成ajax提交的方式,async:false
(async 设置为 false,则所有的请求均为同步请求,在没有返回值之前,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行)
function saveUser() {
doSubmit();
var url = "${ctx}/membermanager/member/save";
var data={
"phone":$("input[name='phone']").val(),
"password":$("input[name='password']").val(),
"truename":$("input[name='truename']").val(),
"email":$("input[name='email']").val(),
"sex":$("input[name='sex']").val(),
"age":$("input[name='age']").val(),
"isIdea":$('input:radio[name="isIdea"]:checked').val(),
"isAd":$('input:radio[name="isAd"]:checked').val(),
"levelId.id":$("select[name='levelId.id']").val()
};
$.ajax({
url : path,
data : data,
type:"post",
dataType:"json",
async : false,
cache : false,
beforeSend:function(){
if(loadingText!=undefined&&loadingText!="")
$.jBox.tip(loadingText, 'loading');
},
complete:function(XHR, TS){
closeTip();
},
success : function(page) {
window.location.href = "${ctx}/membermanager/member/list";
},
error : function(XMLHttpRequest, textStatus, errorThrown){
result = {statusCode:XMLHttpRequest.status,value:XMLHttpRequest.responseText};
}
});
}
后来这个bug仍然出现了,开始怀疑是因为controller层重复调用了dubbo。
项目采用dubbo+zookeeper实现分布式RPC调用。
猜想是网络问题导致的提交重试。
(1)、去掉超时重试机制
<dubbo:provider delay="-1" timeout="6000" retries="0"/>
(2)、重新评估设置超时时间
<dubbo:service interface="*.*" ref="*" timeout="延长服务时间"/>
还是会出现这样的问题,但延长服务时间,不是个很好量化的数字。
后来找到了一篇文章
这样最后一个线索也全断了,在快要放弃的时候,突然看到一堆JSONArray和JSONObject错误,想着会不会是json的问题,最后发现还真实json的问题,大家看看我引用的json就知道了。
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
json-lib的依赖中多了 <classifier>jdk15</classifier> 和jdk1.8冲突,导致堆溢出的。最后我机智的将json-lib改为fastjson依赖就成功的解决这个问题了。
结果测试反馈这个问题又出现了。
哭鸟·····
这次导出线上环境的日志
10.10.111.250 - - [24/May/2019:11:41:45 +0800] "POST /a/membermanager/member/save HTTP/1.0" 200 65
10.10.111.250 - - [24/May/2019:11:41:45 +0800] "GET /a/membermanager/member/list HTTP/1.0" 200 40263
10.10.111.250 - - [24/May/2019:11:41:45 +0800] "POST /a/membermanager/member/save HTTP/1.0" 200 65
10.10.111.250 - - [24/May/2019:11:41:45 +0800] "GET /a/membermanager/member/list HTTP/1.0" 200 40263
10.10.111.250 - - [24/May/2019:11:41:45 +0800] "POST /a/membermanager/member/save HTTP/1.0" 200 65
10.10.111.250 - - [24/May/2019:11:41:45 +0800] "GET /a/membermanager/member/list HTTP/1.0" 200 40263
10.10.111.250 - - [24/May/2019:11:41:52 +0800] "POST /a/membermanager/member/list HTTP/1.0" 200 40041
发现save list这样的接口被调用了多次,所以不是form表单重复提交(async:false),或者是dubbo重复提交的问题。
ajax方法多次执行了,而且是接到了返回值,又重复执行了一遍。
var isCommitted = false;//表单是否已经提交标识,默认为false
function doSubmit(){
if(isCommitted==false){
isCommitted = true;//提交表单后,将表单是否已经提交标识设置为true
return true;//返回true让表单正常提交
}else{
return false;//返回false那么表单将不提交
}
}