X5内核  请求超时后会自动阻止请求返回并由代理服务器将原参数重新发送请求到服务层代码。但由于第一次请求已经请求到服务器,会导致出现重复下单、支付等重大问题。

该问题由于腾讯x5浏览器会自动阻止第一次请求返回到页面,届时将抛出io异常。最开始打算通过拦截器来进行拦截第二次请求,但这样将使页面无法接受到返回信息报错。

初步解决思路 当第二次请求访问进服务层时暂停该线程,并定时循环查询第一次请求是否返回成功,将第一次返回成功的结果赋值给第二次。

由于我们系统中所有页面请求都会过一个通用controller 所以也会有很多正常请求通过 为了不影响整体使用

这里我用到了页面验签的方法,用于验证请求是否为同一次。这里先将参数进行排序,再用md5加密,添加一个“sign”的参数到后台,后台再排序加密进行比对,进行验签,注意这里参数加入了

时间戳,用于防止重复提交

KGF.getMD5 = function(params){
params["key"] = "ouE6yWvy";
var sParams = Object.keys(params).sort();
var oriString = "";
for(key in sParams){
oriString += sParams[key]+"="+params[sParams[key]]+"&";
}
oriString = oriString.substr(0,oriString.length-1);
delete params.key;
return KGF.md5(oriString);
};

验签成功后,由于需要将第一次返回成功的结果赋值给第二次。所以需要将调用接口成功的结果存入seesion中,但此时需要及时去清理,否则容易造成服务器内存溢出。

默认调用接口成功后就将结果集放入session,验签一通过就去取,这里的关键在于何时去删除session中的值。由于所有结果访问均会通过该控制器,为了区分不同的请求,

故用sign作为键,返回结果为值。

下面贴出代码

@RequestMapping(value={"/common/ajax.do"}, method={RequestMethod.POST}, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public List<AjaxResponse> execute2(@RequestHeader(value="Accept", required=false) String accept, HttpServletRequest request){
XMLResults results = new XMLResults();
try{
AjaxObject object = (AjaxObject)request.getAttribute("ParamName");
String openid = (String) request.getSession().getAttribute("openid");
Class[] cArg = new Class[2];
cArg[0] = HttpServletRequest.class;
cArg[1] = Map.class;
DataResult dataResult = new DataResult();
Map<String, Object> params = object.getParams();
String signFromAjax = (String) params.get("sign");
long startTime = 0;
long endTime = 0;
if(!checkSign(params)){
log.error("接口请求验签失败");
dataResult.setRetInfo("-1", "接口请求验签失败", CommonUtil.parseDoubleList(new HashMap()));
}else{
String signFromSession = (String) request.getSession().getAttribute(signFromAjax);
request.getSession().setAttribute(signFromAjax,signFromAjax);
//处理腾讯安卓微信浏览器,10s重发请求的问题
if(signFromSession != null){
for(int i = 0; i <10; i++){
try {
Thread.currentThread().sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("====================重复请求读取接口返回信息:第"+(i+1)+"次====================");
DataResult dataResultFromSession = (DataResult) request.getSession().getAttribute(signFromAjax+"interfaceResult");
if(dataResultFromSession != null){
request.getSession().removeAttribute(signFromAjax);
request.getSession().removeAttribute(signFromAjax+"interfaceResult");
results = this.baseService.convertResult(dataResult);
dataResult = dataResultFromSession;
break;
}
if(i == 9){
dataResult.setRetInfo("-1", "接口请求超时,请联系管理员", CommonUtil.parseDoubleList(new HashMap()));
}
}
}else{
startTime = new Date().getTime();
params.put("requestIp", CommonUtil.getIpAddr(request));
params.put("openid", openid);
params.put("deviceType", CommonUtil.getDeviceType(request));
params.put("browserType", CommonUtil.getBrowserType(request));
params.put("g_stationaddr", CommonUtil.getIpAddr(request));
Method method = commonDataModel.getClass().getDeclaredMethod(object.getCode(), cArg);
dataResult = (DataResult) method.invoke(commonDataModel, request, params);
endTime = new Date().getTime();
request.getSession().setAttribute(signFromAjax+"interfaceResult", dataResult);
}
}
if(endTime - startTime <= 10000){
request.getSession().removeAttribute(signFromAjax);
request.getSession().removeAttribute(signFromAjax+"interfaceResult");
}
results = this.baseService.convertResult(dataResult);
}catch (Exception e){
log.error("数据请求失败,错误信息:" + e.getMessage());
results.setRetInfo("-1", "数据请求失败");
}
return webHelper.convertAjaxResponse(results);
}

微信内置安卓x5浏览器请求超时自动重发问题处理小记的更多相关文章

  1. 2017年05月10日记一次微项目投产 | 安卓版微信内置浏览器不能解析gzip压缩过的mp4视频的问题

    前言 今天投产了一个小项目,一个很简单的H5,有播放视频功能,使用了videojs插件. 之前也做过数个视频播放,视频的转压都按照既定流程进行,文件放到FTP后,iphone和安卓机测试下来都没有问题 ...

  2. 让微信内置浏览器兼容clipboard.js 复制粘贴 ios 安卓

    <!--js copy事件--><script type="text/javascript" src="/static/js/clipboard.min ...

  3. 微信内置浏览器http请求10秒内接收不到数据会自动重发第二遍请求

    微信内置浏览器http请求10秒内接收不到数据会自动重发第二遍请求     这是个坑

  4. asp.net微信内置浏览器下Session失效

    问题记录:仅限安卓端微信内置浏览器,服务器集群设置了黏性Session,在Post请求时会强制走代理,导致出去的ip指向另一台服务器,黏性Session失效,用户状态无法保存. 目前想知道除了设置Se ...

  5. 微信内置浏览器WebApp开发,踩坑 · Issue #31 · maxzhang/maxzhang.github.com · GitHub

    最近花6天时间完成了一个七夕的小活动,是一个简单的WebApp.由于我前期对面向微信的Web开发评估不足,导致开发过程十分艰难.写这篇文章总结下,惊醒自己未来不要再犯这样的错误. 问题: 1. 有些比 ...

  6. 微信内置浏览器的JsAPI(WeixinJSBridge续)[转载]

    原文地址:  http://www.baidufe.com/item/f07a3be0b23b4c9606bb.html 之前有写过几篇关于微信内置浏览器(WebView)中特有的Javascript ...

  7. 【微网站开发】之微信内置浏览器API使用

    最近在写微网站,发现了微信内置浏览器的很多不称心的地方: 1.安卓版的微信内浏览器底部总是出现一个刷新.前进.后退的底部栏,宽度很大,导致屏幕显示尺寸被压缩 2.分享当前网站至朋友圈时,分享的图片一般 ...

  8. 微信内置浏览器中,点击下拉框出现页面乱跳转现象(iphone)

    微信内置浏览器中,点击下拉框出现页面乱跳转现象(iphone) 前言: 这是小菜博客的第三篇文章.一直认为自己可以表达的东西太过简单,难以上台面,总是吝啬地不肯写.就算是写,也不知道从何开始.在同事的 ...

  9. 微信内置浏览器的JsAPI(WeixinJSBridge续)_Alien的笔记

    微信内置浏览器的JsAPI(WeixinJSBridge续)_Alien的笔记 微信内置浏览器的JsAPI(WeixinJSBridge续)进入全屏 之前有写过几篇关于微信内置浏览器(WebView) ...

随机推荐

  1. Angular4中路由Router类的跳转navigate

    最近一直在学习angular4,它确实比以前有了很大的变化和改进,好多地方也不是那么容易就能理解,好在官方的文档和例子是中文,对英文不太好的还是有很大帮助去学习. 官方地址:https://angul ...

  2. CentOS 6.x 如何升级 glibc 2.17

    CentOS 6.x 如何升级 glibc 2.17 ldd --version rpm -qa | grep glibc #查看glibc的版本 strings /lib64/libc.so.6 | ...

  3. 【linux】在宝塔上 同ip 不同端口 设置一个端口对应一个网站

    准备工作: ip一个 , 例如:192.168.1.666 服务器一台,放行所需端口 假想一个域名 www.test.com ps:默认你已经装好宝塔面板了 实现效果: 192.168.1.666:6 ...

  4. [EMSE'17] A Correlation Study between Automated Program Repair and Test-Suite Metrics

    Basic Information Authors: Jooyong Yi, Shin Hwei Tan, Sergey Mechtaev, Marcel Böhme, Abhik Roychoudh ...

  5. python nose测试框架全面介绍十二 ----用例执行顺序打乱

    在实际执行自动化测试时,发现我们的用例在使用同一个资源的操作时,用例的执行顺序对测试结果有影响,在手工测试时是完全没法覆盖的. 但每一次都是按用例名字来执行,怎么打乱来执行的. 在网上看到一个有意思的 ...

  6. windows修改PowerShell(命令提示符)默认中文编码方式

    如果以下方法都没有作用的话,可以直接在代码中调用<stdlib.h>中的system("mode con cp select=65001")或者是system(&quo ...

  7. 算法提高 金属采集_树形dp

    算法提高 金属采集   时间限制:1.0s   内存限制:256.0MB        问题描述 人类在火星上发现了一种新的金属!这些金属分布在一些奇怪的地方,不妨叫它节点好了.一些节点之间有道路相连 ...

  8. 6.1 Pandora 实操 - 数据收集

    添加机器 添加机器命令,在 linux 机器上执行此命令 添加成功 添加收集器 采集机器数据 解析数据 转换数据 发送数据 接着,下一步即,成功创建收集任务. 分发机器 确认收集人物,绑定到机器上. ...

  9. ArcGIS AddIN 与ArcMap自带工具进行交互

    参考示例代码:C:\Program Files (x86)\ArcGIS\DeveloperKit10.1\Samples\ArcObjectsNet\Brushing 核心代码: //获取Selec ...

  10. ArcEngine临时数据存储 创建内存工作空间

    参考网址,这里 工作中有时候需要使用临时数据,以前都是创建一个默认的shapefile或者gdb,今天发现esri官方帮助文档给出了一个方法,可以创建内存工作空间,代码如下: public stati ...