对于DWR工具来说,主要是提供了页面与后台程序的交互功能;
而CXF,则主要是实现Web Service。
将两者结合使用,将可以是使我们的应用可以在Web Service系统中实现页面的无刷新。
这里,我在项目中也确实感受到了它的便利。
但是,我们知道,CXF的远程请求是需要一些时间的,根据各个服务的运算复杂性和网络通信优劣程度,时间也有很大差异,那么,通过DWR对CXF发起请求时,我们就要很严格地控制了,要确保我们得到的数据就是我们需要的正确数据。
比如,页面上有一个select控件,每个选项对应网络上的一个服务器地址(并不保证都能正常访问)。
我们有可能使用DWR向远程服务器A发送请求A,由于其他原因,请求A未能立即返回结果A;
接着,我们又向远程服务器B发送请求B,请求B很快返回结果B,页面上将结果B展示了出来;过一会,结果A也返回了,但是,页面也同样将结果A展示了出来。
那么,结果A将结果B覆盖了,很明显,这是很不合理的。
处理这个的方法应该很多的,这里我只提出两个,一个是我个人的,一个是DWR自身的。
一、通过DWR自身的设置,将传输设置为同步的(默认是异步的)。如下
//设置成同步
DWREngine.setAsync(false);
//其他代码
//……
//重新设置为异步方式
DWREngine.setAsync(true);
二、通过设定一个判定值来确定返回的是哪一次请求结果。代码如下:
var requestFlag = 1; //请求变量
var returnFlag = 1; //返回变量
// 事件触发函数
function getExams(ws_id){
requestFlag ++; //请求变量
returnFlag ++; //返回变量
requestExams(ws_id, requestFlag);
}
// 远程请求调用
function requestExams(ws_id, reqFlag){
var flag1 = reqFlag;
// wsUtil为某个DWR映射对象。
wsUtil.getExamList(ws_id, function(data){setExams(flag1, data);});
}
// 处理返回结果
function setExams(_requestFlag, data){
if(_requestFlag != returnFlag){
return ; // 请求变量与返回变量不一致,说明已经又发起了新的请求,旧请求的结果不做任何处理。
}
// 以下为返回结果的处理
$("").innerText = "返回结果为:" + data;
}
下面,我们来比较一下这两个方法的优劣。
在第一种方法中,我们很明显可以看出,代码简洁、方便维护等。唯一的不足就是,DWR的每次请求,都要等待前面的请求结果处理完后才进行。假如我们连续请求了两个不同的webservice地址,但先是一个无效的webservice地址,那么它需要进行一段时间的尝试访问,才能将错误返回;(注:虽然这个时间是可以控制的,但考虑到远程的因素,我们不能将时间设置太短,所以,无论如何,都需要开销一点时间。) 紧接着,才能处理后一个请求。这样,让用户等待了较长时间,这很不符合我们的用户体验设计思想,同时,仍然会对旧操作的数据进行处理。
第二中方法中,由于是自行添加的代码,看起来不是那么的简洁明了。但是,可以减少用户等待的时间,并能避免处理旧请求的数据处理。
至于以上两种方法该采用哪一种,只有看实际需求了。
补充说明:
在第二种方法的代码中,有这么一个语句:
wsUtil.getExamList(ws_id, function(data){setExams(flag1, data);});
这里,其实DWR的回调函数是function(data){},而不是setExams。这么写的目的就是将返回变量的值传入实际的执行函数 setExams中。