Web Service与DWR结合使用时的一些技巧

来源:互联网 发布:刘昊然网络剧 编辑:程序博客网 时间:2024/05/22 07:55

对于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中。