js的webservice客户端的设计开发与应用

   欢迎来到:http://observer.blog.51cto.com

   webservcie是可以跨语言跨平台开发的一种技术,各种计算机语言都可以搭建服务器,同时各种计算机语言也可以开发客户端。只要有服务器,不管是用java还是C++抑或是php搭建的,其他语言都可以根据其开放的wsdl开发好客户端,然后调用其方法就像调用本地本项目的方法一样。本文使用js开发客户端,例子依赖于上一篇文章:CXF搭建webService服务器;如果有不明白的可以先看此文章再看本文。
   使用js编写webservice客户端,有很多方法,使用CXF自带wsdl2js命令也是可以的,但是这个命令出来的js代码简直不能接受,太乱了,一大陀代码不好控制,还是算了吧!这里介绍的是自己使用js编写客户端的方法。
第一步:编写xml
   根据发布的wsdl编写xml。这里就出现问题了,要是对wsdl不了解的,怎么编写呢?而且还容易出错,到时候简直不知道是自己xml错了还是js代码错了。呵呵,这里介绍一个很好用的实现web service和web service的功能/负载/符合性测试的工具:soapui。此工具可以根据wsdl生成xml,然后测试。
   下载soapui(因为文件太大,我就上传liunx的行了,windows的朋友尽可以自己上网搜一下。):soapui-4.5.1_for_liunx
   下载后解压,进入soapui-4.5.1/bin后运行soapui.sh(windows的朋友自行运行安装好的soapui)如下图:


   右键Projects――>new soapui project,在新出现的窗口project name(可以自定义)与initial wsdl/wadl一栏中都填上wsdl如下图:

   点击ok就可以在projects下看到已将连接的webservice,双击对应的webservcie的方法下面的request 1就会看到soapui根据wsdl自动给我们生成的xml,在xml里面找到自己定义的方法的变量名,填上变量,点击request 1窗口左上角的运行按钮进行测试,能够得到结果就证明webservice测试通过,如我的测试如下图:

第二步:编写js代码
   首先获取HTTP协议的安全的访问对象,然后发送请求,上代码:

function serviceHelloWrod() {
      var serviceWsdl = 'http://127.0.0.1:8080/webServiceCXF/services/Service?wsdl';
      //连接webservice的wsdl
    var serviceUrl = 'http://www.observer.com/service';
    //自己定义的url,这个值就是服务器端,定义接口时的targetNamespace
    //因为服务器一旦定义运行,serviceWsdl跟serviceUrl就不会轻易改变,所以这里将这两个值定义在js文件中
    function getXMLRequester() {//此方法获取对HTTP协议的安全的访问的XMLHttpRequest对象
        var xmlhttp_request = false;
        try {
            if (window.ActiveXObject) {
                xmlhttp_request = new ActiveXObject('Microsoft.XMLHTTP');
                //在 IE 5 和 IE 6 中,必须使用特定于 IE 的 ActiveXObject() 构造函数
            } else if (window.XMLHttpRequest) {
                xmlhttp_request = new XMLHttpRequest();
                if (xmlhttp_request.overrideMimeType) {
                    xmlhttp_request.overrideMimeType('text/xml');
                }
            }
        } catch (e) {
            xmlhttp_request = false;
            alert('Sorry your browser version is too low, please update after use.');
        }
        return xmlhttp_request;
    };
    var xmlhttp = getXMLRequester();
    function requestByPost(data) {//向webservice发送请求,得到返回的xml,然后解析xml得到返回值
        var URL = serviceWsdl;
        xmlhttp.open('POST', URL, false);
        xmlhttp.setRequestHeader('Content-Type', 'text/xml;charset=utf-8');
        xmlhttp.setRequestHeader('SOAPAction',
                'http://dao.wfservice.ws.emolay.com');
        xmlhttp.send(data);//发送请求
        var str = xmlhttp.responseText;//得到反馈的xml
        var xmlDoc = new DOMParser().parseFromString(str, 'text/xml');//解析xml
        var result = xmlDoc.getElementsByTagName('result');
        return result;
    };
    function getGradeName(toid) {
        //编辑发送请求的xml(data变量),然后调用requestByPost方法请求webservice,这里的xml完全可以使用soapui自动生成
        var data = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="' + serviceUrl + '">';
        data += '<soapenv:Header/>';
        data += '<soapenv:Body>';
        data += '<ser:getGradeName>';
        data += '<toid>' + toid + '</toid>';
        data += '</ser:getGradeName>';
        data += '</soapenv:Body>';
        data += '</soapenv:Envelope>';
        var result = requestByPost(data);
        var str = [];
        for ( var i = 0; i < result.length; i=i+1) {
            str.push(result[i].firstChild.nodeValue);
            //因为webservice返还之不一定只是一个string,也可能是一个数组等等,所以xml标签中不一定只有一个结果,
            //所以必须一个一个解析出来,然后拿到里面的值。当然,如果真正确定了服务器的返回值个数,也可以将其固定起来
        }
        return str;
    };
    function getTest(toid){
        //连接webservice
        return "test:"+toid;
    }
    function getMeans(means){//根据所给的参数返回方法
        if(means=="getGradeName"){
            return getGradeName;
        }else if(means=="getTest"){
            return getTest;
        }else{
            return null;
        }
    }
    return getMeans;
}

   到这里,客户端已经开发完成,以上技术上的问题就不多说了,代码中已经的注释得很清楚,如果想看更详细的可以下载附件,这里需要说一下设计
   首先,客户端的js代码使用的是闭包(closure)编写的,可移植性强,只要保证调用页面没有重复的serviceHelloWrod方法就可以像组件一样拿去使用,不用担心因为里面的变量或者方法有重复而使js出错。
   其次,该客户端组建模仿java中的映射,初始化方法之后会返回getMeans方法,此方法可以根据传给它的参数返回一个webservcie连接的方法,让调用者调用,如果没有这个方法,则返回null,调用失败。就像java中的映射一样,你不需要知道这个方法是什么,只要你知道webservice中有这个方法,你就可以根据一个字符串得到这个方法,然后传参调用它。此设计同时也易于扩展,如果webservice中添加了方法,比如说以上的添加了getTest方法,可以直接在js中添加function getTest(toid),然后在getMeans中添加可以返回的判断即可。
第三步:应用客户端
   初始化客户端,然后返回相应的方法,然后调用,如在html中可以这样调用:

<script type="text/javascript">
    var toid = 123;
    var means = serviceHelloWrod();//初始化
    var str = means("getGradeName")(toid);//调用方法
</script>

   我的应用如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <script src="js/service.js" type="text/javascript"></script>
        <script type="text/javascript">
            function runServiceC(showjs){
                var toid = 123;
                var means = serviceHelloWrod();//初始化
                var str = means("getGradeName")(toid);//调用方法
                document.getElementById(showjs).innerHTML = str;
            };
          </script>
        <title>webServiceClientJs</title>
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="this is my page">
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
    </head>
    <body>
        <div align="center">
            <p id="showjs1"></p>
        </div>
        <div align="center">
            show Service :
            <font id="showjs2">run before</font>
            <br />
            <button type="button"                 运行service客户端
            </button>
            <button type="button"
                onclick="(function(){document.getElementById('showjs2').innerHTML = 'run before';})();">
                还原show Service
            </button>
        </div>
    </body>
    <script type="text/javascript">
    //直接定义一个没有名字的方法,然后马上运行
    (function() {
        runServiceC("showjs1");
    })();
</script>
</html>

   (非常抱歉的说,上面的html代码放上去发布后总是显示乱代码,看不懂的朋友可以下载附件看)这里的toid等需要动态生成的参数,可以根据jsp或者php等其他动态建站语言生成,最后想要怎样应用,应用成怎么样就看自己的具体案例具体分析了。
   到这里,js的webservice客户端的设计开发与应用已经讲完,附上项目,如果对java的webservice感兴趣,可以看看这篇文章: java中webservcie客户端的设计开发与应用

   后面会继续放上关于技术与设计方面的文章,期待您的关注,谢谢。

你可能感兴趣的:(JavaScript,webservice客户端)