今天终于完成了ajax服务 异步和同步的两种调用方式 在超时和断网情况下的异常处理(累死我了,用了两周才搞定)! 下面就总结下。
1.谈谈ajax的两种服务调用方式:
虽说AJAX是异步实现的,并且AJAX确实是为了异步的实现才引入近来的。但是,AJAX仍然也支持同步的调用。XMLHttpRequest的open函数第三个参数,可以设定调用方式,如下:XMLHttpRequest.open(String method,String URL,boolean async)其中的async就是是否同步的参数了。true表示异步调用,false则表示异步调用。
2.异步方法的超时断网设定
2.1超时处理:
异步的方法可以在js中,在使用setTimeout函数进行设定。setTimeOut函数可以放在xmlhttp.onreadystatechange函数前后执行。代码如下:
xmlhttp.onreadystatechange = function(){ if (xmlhttp.readyState == 4) { if (xmlhttp.status == 200){ var result = xmlhttp.responseText; if(scope){ callback(result,scope); }else{ callback(result); } xmlhttp = null; } } xmlhttp.send(params); var time = '20000';//超时时间 设定为20S var timeoutHandler = setTimeout(function(){ if(xmlhttp){ //取消本次ajax调用 xmlhttp.abort(); xmlhttp = null; if(confirm("调用后台服务超时。选择'确定',将重新调用该服务; 选 择'取消',将清空购物车")){ //点击确定则重新调用该服务 return _callService(servName,params,callback,scope); }else{ //清空购物车 clearFormActionForTimeOut(); } } clearTimeout(timeoutHandler); },time); }
设置了20S的超时时间,超过20S则会执行setTimeout函数体。
2.2 断网处理
ajax异步调用时,出现完全断网时,xmlhttp.status的响应状态为0。我是把xmlhttp.status的状态为0,认为是断网的响应结果(没有通过Web服务器形式的Ajax请求返回值都是0,也可叫本地响应成功。因为的我的服务都是正常的服务器调用,正常情况下不会为0)。当执行xmlhttp.abort()时,也会导致xmlhttp.status的状态为0。所以我做了如下处理,代码如下:
var ajaxSuccesFlag = false;//为true 则表示服务已经超时了
xmlhttp.onreadystatechange = function(){ if (xmlhttp.readyState == 4) { if (xmlhttp.status == 200){ var result = xmlhttp.responseText; if(scope){ callback(result,scope); }else{ callback(result); } }else if(!ajaxSuccesFlag && xmlhttp.status == 0){ //服务器找不到,本地响应成功。排除超时,执行的xmlhttp.abort()导致的响应 xmlhttp = null; alert("调用规则服务异常,将会清空购物车;请检查网络后 重新办理!") //清空购物车 clearFormActionForTimeOut();
} xmlhttp = null; } } xmlhttp.send(params); var time = '20000';//超时时间 设定为20S var timeoutHandler = setTimeout(function(){ if(xmlhttp){ ajaxSuccesFlag = true; xmlhttp.abort(); xmlhttp = null; //清空购物车 clearFormActionForTimeOut(); } clearTimeout(timeoutHandler); },time); }
}
3.同步方法的超时断网设定
3.1 超时设定:
ajax的同步方法,设置的setTimeOut函数发现没有按照自己想要的执行,也就是该函数要在服务调用,响应结果后,才开始计时,不能达到自己想要的结果。于是只能在服务器进行超时控制。先看代码:
public void test(Request req,Response rsp) { final ExecutorService exec = Executors.newFixedThreadPool(1); final JSONObject olInfo = JSONObject.fromObject(req.getEntityAsJson()); final String areaId = RouteUtil.getCurRequestAreaId(); String returnCode = "0"; Callable<String> call = new Callable<String>() { public String call() throws Exception { // 开始执行耗时操作 log.debug("fillDataBeforeCash...param={}",olInfo.toString()); Long olId = olInfo.getLong("olId"); RouteUtil.setCurRequestAreaId(areaId); getSoSaveSMO().fillDataBeforeCash(olId); return "线程执行完成."; } }; Future<String> future = exec.submit(call); try { String obj = future.get(60000,TimeUnit.MILLISECONDS); // 任务处理超时时间设为 1 分钟 } catch (TimeoutException ex) { log.error("处理超时啦....:{}",ex); returnCod e = "-100021"; //返回超时状态为前台 进行相应处理 future.cancel(true);//超时则中断该Callable线程,只是对Callable线程进行了interrupt()操作,并不一定会导致该线程销毁
} finally { // 关闭线程池 exec.shutdown(); } log.debug("返回前台数据:{}",returnCode); rsp.setEntityAsJson(returnCode); }
我使用了 jdk1.5自带的并发库中Future类就能进行java服务超时设置。Future类中重要方法包括get(timeout)和cancel()。 而
cancel()是取消数据加载。而get(timeout)操作,表示如果在timeout时间内没有取到就失败返回,而不再阻塞。
3.2断网处理:
同步的ajax调用,当遇到断网的情况时,xmlhttp.send(params)会抛出“Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [XMLHttpRequest.send]”。
对该异常进行捕获,进行相应处理!