使用javascript调用webservice示例

鉴客 发布于 2011/12/14 16:35
阅读 2K+
收藏 0

再javascript中使用soap调用webservice的示例代码

代码再IE6和FF测试通过,对于c#写的webservice和java(xfire)写的,都测试过,没有问题

此代码原型来源于 http://www.guru4.net/ 的javascript soapclient

发现这个下载的js只能用于调用c#的webservice,所以利用mootools,重新封装,达到IE和火狐的兼容的同时,兼容java和c#

(再例子中使用的 mootools.v1.11.js 文件,做过修改)

客户端js调用代码如下

function ajaxRequest()   
    {   
        var url = "http://localhost:88/webservicedemo.asmx";   
           
        //设置webService传入参数   
        //   
        //注意:   
        //   
        //    调用.Net 写的webservice(如例子中的webservicedemo.asmx)   
        //           HelloTo(String name)   针对name参数必须写成 <name></name>wqj,还有更多参数一样写,使用名称匹配   
        //           传入的参数数量可以不等于(多于或少于)方法要求的参数   
        //   
        //    调用java(xfire) 发布的webService   
        //           传入的参数必须与调用方法的参数数量相等,且按传入值的顺序进行匹配   
        //   
           
        var para = "<name></name>wqj"; 这里应该是一个标准的xml形式,源码贴出来时被虑掉了,请参看附件源码  
           
        var op = {   
                    data:para,   
                    onComplete: showResponse,   
                    onFailure:showError,   
                    update:'ajaxBack'   
                 };   
  
        var service = new WebService(url,"HelloTo",op);   
        service.request();   
        return false;   
    }   
    function showError(obj)   
    {   
        //obj 是一个xmlHttpRequest对象   
        alert("error");   
    }   
    function showResponse(requestText,requestXML)   
    {   
        //requestText 返回的文本   
        //requestXML 返回的XML   
        alert("ok");   
    } 

WebService类的代码如下(webservice.js)
var WSDLS = {};   
  
var WebService = new Class({   
  
    url : '',   
    method : '',   
    options:    
    {   
        method:'GET',   
        data: null,   
        update: null,   
        onComplete: Class.empty,   
        onError:Class.empty,   
        evalScripts: false,   
        evalResponse: false  
    },   
       
    initialize: function(url,method,options)   
    {   
        this.url = url;   
        this.method = method;   
        this.options = options;   
  
    },   
       
    request : function()   
    {   
        var wsdl = WSDLS[this.url];   
        if(!wsdl)    
        {   
            var op = {method:'GET',async: false};   
            var wsdlAjax = new XHR(op).send(this.url + "?wsdl", null);             
            wsdl = wsdlAjax.transport.responseXML;   
            WSDLS[this.url] = wsdl;   
        }   
        this.setSoap(wsdl);   
    },   
           
    setSoap : function(wsdl)   
    {   
           
        var ns = (wsdl.documentElement.attributes["targetNamespace"] + "" == "undefined") ? wsdl.documentElement.attributes.getNamedItem("targetNamespace").nodeValue : wsdl.documentElement.attributes["targetNamespace"].value;   
        var sr =    
                "" +   
                ""
                "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +   
                "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +   
                "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +   
                "<soap:body>"</soap:body> +   
                "<" + this.method + " xmlns=\"" + ns + "\">" +   
                     (this.options.data === null ?"":this.options.data) +   
                " + this.method + ">;   
           
        this.options.method = 'post';   
        this.options.data = null;   
           
        var soapaction = ((ns.lastIndexOf("/") != ns.length - 1) ? ns + "/" : ns) + this.method;   
           
        var soapAjax = new Ajax(this.url,this.options);   
        soapAjax.setHeader("SOAPAction", soapaction);   
        soapAjax.setHeader("Content-type", "text/xml; charset=utf-8");   
        soapAjax.request(sr);   
    }   
       
}); 

在第一个版本中存在以下问题

1. 不能根据webservice的要求输入参数自动组织参数

2. 没有处理返回值

3.一旦webservice调用过程出错,会形成一个死循环(一直弹出error)


V2 说明

1. 解决第一版中死循环的问题

2. 统一输入参数的传入形式(与mootools的ajax使用方式完全一致),形式如name=wqj&age=20&........

3. 自动根据参数名对应的值,组织webservice的传入参数,只根据webservice要求的参数名查找对应的值

    与顺序不再有关系.(对于xfire中的输入参数使用名称 in0,in1........)

    传入的参数数量也不再要求一致,多的自动丢弃,少的自动传空

4. 对于返回的XML,增加提取方法,返回需要的关键返回值(去掉XML的框框)

详细参照附件源码,下面是部分关键代码


WebService类的代码如下(webservice.js)

    var WSDLS = {};  
      
    var WebService = new Class({  
      
        url : '',  
        method : '',  
        options:   
        {  
            method:'GET',  
            data: null,  
            update: null,  
            onComplete: Class.empty,  
            onError:Class.empty,  
            evalScripts: false,  
            evalResponse: false  
        },  
          
        initialize: function(url,method,options)  
        {         
            this.url = url;  
            this.method = method;  
            this.options = options;  
        },  
          
        request : function()  
        {  
            var wsdl = WSDLS[this.url];  
            if(!wsdl)   
            {  
                var op = {method:'GET',async: false};  
                var wsdlAjax = new XHR(op).send(this.url + "?wsdl", null);            
                wsdl = wsdlAjax.transport.responseXML;  
                WSDLS[this.url] = wsdl;  
            }  
      
            this.setSoap(wsdl);  
        },  
              
        setSoap : function(wsdl)  
        {  
            var paraXML = this.getParaXML(wsdl);  
            alert(paraXML);  
            var ns = (wsdl.documentElement.attributes["targetNamespace"] + "" == "undefined") ? wsdl.documentElement.attributes.getNamedItem("targetNamespace").nodeValue : wsdl.documentElement.attributes["targetNamespace"].value;  
            var sr =   
                    "" +  
                    " +  
                    "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +  
                    "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +  
                    "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +  
                    "<soap:body>"</soap:body> +  
                    "<" + this.method + " xmlns=\"" + ns + "\">" +  
                        paraXML  +  
                    " + this.method + ">";  
              
            this.options.method = 'post';  
            this.options.data = null;  
              
            var soapaction = ((ns.lastIndexOf("/") != ns.length - 1) ? ns + "/" : ns) + this.method;  
      
            var soapAjax = new Ajax(this.url,this.options);  
            soapAjax.setHeader("SOAPAction", soapaction);  
            soapAjax.setHeader("Content-type", "text/xml; charset=utf-8");  
            soapAjax.request(sr);   
        },  
        getParaXML : function(wsdl)  
        {  
              
            var objNode = null;  
            var rtnValue = "";  
            //java(xfire)  
            var ell = this.getElementsByTagName(wsdl,"xsd:element");      
            if(ell.length == 0)   
            {  
                //c#  
                ell = this.getElementsByTagName(wsdl,"s:element");    
            }  
            for(var i = 0; i < ell.length; i++)  
            {  
                if(this.getElementAttrValue(ell[i],"name") == this.method)  
                {  
                    objNode = ell[i];  
                    break;  
                }  
            }  
      
            if(objNode == null) return rtnValue;  
            //java(xfire)  
            ell = this.getElementsByTagName(objNode,"xsd:element");   
            if(ell.length == 0)   
            {  
                //c#  
                ell = this.getElementsByTagName(objNode,"s:element");  
            }  
            if(ell.length == 0) return rtnValue ;  
              
            var hash = new Hash();  
              
            if(this.options.data != null && this.options.data.clean != "")  
            {  
                hash = this.options.data.split("&").toHash("=");  
            }  
              
            for(var i = 0; i < ell.length; i++)  
            {  
                var paraName = this.getElementAttrValue(ell[i],"name");  
                rtnValue = rtnValue + this.getSingleXML(paraName,hash);  
            }  
              
            return rtnValue;  
        },  
          
        getSingleXML : function (name,hash)  
        {  
            name = name.trim();  
              
            var rtnValue = "";  
            if(hash.hasKey(name))  
            {  
                rtnValue = hash.get(name);  
            }  
            rtnValue = "<" + name + ">" + xmlscc(rtnValue) + " + name + ">"  
            return rtnValue;  
        },  
        getBackData: function(xml)  
        {  
            var rtnValue = "";  
            //java(xfire)  
            var soap = this.getElementsByTagName(xml,"ns1:out");      
            if(soap.length == 0)  
            {  
                //c#  
                soap = this.getElementsByTagName(xml,this.method + "Result");  
            }  
            return soap[0].childNodes[0].nodeValue;       
              
        },  
        getElementsByTagName : function(objNode,tagName)  
        {  
            //tagName 形式如 xsd:element ,写出tag的全称  
      
            var ell;  
            if(this.isIE())  
            {  
                ell = objNode.getElementsByTagName(tagName);      
            }  
            else  
            {  
                if(tagName.contains(":")) tagName = tagName.split(":")[1];  
                ell = objNode.getElementsByTagName(tagName);           
            }  
            return ell;  
        },  
        getElementAttrValue : function(objNode,attrName)  
        {  
            var rtnValue = "";  
              
            if(objNode == null) return rtnValue;  
              
            if(objNode.attributes[attrName] + "" == "undefined")  
            {   
                if(objNode.attributes.getNamedItem(attrName) != null)  
                    rtnValue = objNode.attributes.getNamedItem(attrName).nodeValue ;  
                  
            }  
            else  
            {  
                if(objNode.attributes[attrName] != null)  
                    rtnValue = objNode.attributes[attrName].value;  
            }  
            return rtnValue;  
        },  
        isIE : function()  
        {  
            var isMSIE = /*@cc_on!@*/false; ; 
            return isMSIE;  
        }  
    });  
      
    Array.extend({  
          
        toHash : function (splitChar)  
        {  
            var hash = new Hash({});  
            for(var i=0;i<this.length;i++)  
            {  
                  
                if(this[i].split(splitChar).length == 1) contrnue;  
      
                var key = this[i].split(splitChar)[0].trim();  
                var value = this[i].split(splitChar)[1].trim();  
                  
                hash.set(key, value);  
            }  
              
            return hash;  
        }  
    });  
      
    function xmlscc(strData)  
    {  
      
        strData=strData.replace(/&/g, "&");  
        strData=strData.replace(/>/g, ">");  
        strData=strData.replace(/"<");  
        strData=strData.replace(/"/g, """); 
        strData=strData.replace(/'/g, "'");  
        return strData;  
    }  

相应的调用代码如下:
    <script type=< span="">"text/javascript">  
          
        var service ;  
        function ajaxRequest()  
        {  
            var url = "http://localhost:88/webservicedemo.asmx";  
              
            //设置webService传入参数  
            //  
            //注意:  
            //  
            //    调用webservice(如例子中的webservicedemo.asmx)  
            //           HelloTo(String name)   针对name参数必须写成name=wqj ,还有更多参数一样写,使用&符号分隔(name=11&age=20&.....),使用名称匹配  
            //           传入的参数数量可以不等于(多于或少于)方法要求的参数  
              
              
            var para = "name=wqj";  
              
            var op = {  
                        data:para,  
                        onComplete: showResponse,  
                        onFailure:showError,  
                        update:'ajaxBack'  
                     };  
      
            service = new WebService(url,"HelloTo",op);  
            service.request();  
            return false;  
        }  
        function showError(obj)  
        {  
            //obj 是一个xmlHttpRequest对象  
            alert("error");  
        }  
        function showResponse(requestText,requestXML)  
        {  
            //requestText 返回的文本  
            //requestXML 返回的XML  
            // service.getBackData 就是取出返回的XML中,实际需要的数据  
            //经过测试兼容 IE,FF  
            alert(service.getBackData(requestXML));  
              
        }  
        </script>  

文章出处: http://www.iteye.com/topic/98182
加载中
0
lugesot
lugesot

没细看,感觉很强大。我原以为RESTful API 是取代SOAP的王道。

没想到前端可以这么好的可以和web service交互。

返回顶部
顶部