您的位置:首页 > 其它

一个调用ATL Server WebServices 的AJAX客户端

2006-09-07 14:17 344 查看
请将下面的代码完整复制到soapclient.js中




/**//*****************************************************************************


 AJAX


 Javascript "SOAP Client" library


 Thank to Mr.Matteo Casati, Ihar Voitka - http://www.guru4.net/


 Author: ZhangLiang, E-Mail:cheungmine@gmail.com


 Date: 2006-8-31


*****************************************************************************/




function _debug(rownum, msg) ...{    alert(rownum+":"+msg);  }




var SOAP_SUCCESS = 0;


var SOAP_FAULT = 1;




var _sr_env_hdr_ =  "<soap:Envelope " +


     "xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" " + 


     "xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" " + 


     "xmlns:xsd="http://www.w3.org/2001/XMLSchema" " + 


     "xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">";


               


var _sr_body_hdr_ = "<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">";




var _soap_header_m_token_ = "";        // global varible, soap_header: m_token




function SOAPParams(callid, url, method, async, callback, username, password)




...{


    this.callid = callid;


    this.url =     url;    // "http://localhost/MtkWebgisServer/MtkWebgis.dll?Handler=GenMtkWebgisWSDL";


    this.svc = null;    //"http://cl2/MtkWebgisServer/MtkWebgis.dll?Handler=Default";    // 未完


    this.method = method;


        


    if (async+"" == "undefined")


        this.async = true;                    // default value


    else


        this.async = async;


        




    if (this.async)...{


        if (callback+"" == "undefined")


            this.callback = soap_callback;


        else


            this.callback = callback;


    }


        


    this.username = null;


    if (username+"" != "")


        this.username = username;


        


    this.password = null;


    if (password+"" != "")


        this.password = password;


        


    this.wsdl = null;


    this.result = SOAP_FAULT;


    this.xmlhttp = null;            // xmlhttp object returned


    


    this._pl = new Array();            // input parameters list


        




    this.add = function(name, value)...{


        this._pl[name] = value;


        return this;


    }


    




    this.toXml = function()...{


        var xml = "";




        for(var p in this._pl)...{


            var t = typeof(this._pl[p]);


            if (t == "object" || t == "function")


                xml += "<" + p + ">" + this._pl[p].toXml() + "</" + p + ">";


            else


                xml += "<" + p + ">" + this._pl[p].toString().replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">") + "</" + p + ">";


        }


        return xml;    


    }


    




    this.setToken = function()...{




        if (this.method=="login")...{


            _soap_header_m_token_ = this.getval("snp:m_token");


        }


    }


    




    this.getToken = function()...{


        return _soap_header_m_token_;


    }


    




    this.getval = function(name)...{


        var ret = SOAPClient._getElementsByTagName(this.xmlhttp.responseXML.documentElement, name).item(0);


        return ret.text;    


    }


    




    this.retval = function()...{


        return this.getval("return");


    }


        


    // SOAP:Fault




    this.faultcode = function()...{


        return this.getval("faultcode");


    }


    




    this.faultstring = function()...{


        return this.getval("faultstring");


    }


    




    this.faultdetail = function()...{


        return this.getval("detail");


    }


}






function SOAPClient()...{}




SOAPClient.invoke = function(params)




...{


    params.result = SOAP_FAULT;


    if(params.async)


        SOAPClient._loadWsdl(params);


    else


        return SOAPClient._loadWsdl(params);


}




// private: wsdl cache


SOAPClient_cacheWsdl = new Array();




// private: invoke async


SOAPClient._loadWsdl = function(params)




...{


    // load from cache?


    params.wsdl = SOAPClient_cacheWsdl[params.url];




    if(params.wsdl + "" != "" && params.wsdl + "" != "undefined")...{


        params.svc = SOAPClient._getService(params.wsdl);    


        return SOAPClient._sendSoapRequest(params);


    }


        


    // get wsdl


    var _xmlhttp = SOAPClient._getXmlHttp();


    


    if (params.username+"" != "undefined")


        _xmlhttp.open("GET", params.url, params.async, params.username, params.password);


    else


        _xmlhttp.open("GET", params.url, params.async);


    




    if(params.async)...{




        _xmlhttp.onreadystatechange = function()...{


            if(_xmlhttp.readyState == 4)


                SOAPClient._onLoadWsdl(params, _xmlhttp);


        }


    }


    


    _xmlhttp.send(null);


    if (!params.async)


        return SOAPClient._onLoadWsdl(params, _xmlhttp);


}




SOAPClient._onLoadWsdl = function(params, req)




...{




    if (req.readyState == 4 && req.status == 200)...{


        params.wsdl = req.responseXML;


        params.svc = SOAPClient._getService(params.wsdl); 


        SOAPClient_cacheWsdl[params.url] = params.wsdl;        // save a copy in cache


        return SOAPClient._sendSoapRequest(params);


    }


    return SOAP_FAULT;


}




SOAPClient._sendSoapRequest = function(params)




...{


    // get namespace, ok


    var ns = SOAPClient._getAttribValue(params.wsdl.documentElement, "targetNamespace");




    // 构造SOAP请求, SOAP 2.0


    var sr =     _sr_env_hdr_ + "<soap:Header><snp:m_token xmlns:snp=""+ns+"">" + 


                _soap_header_m_token_ + "</snp:m_token></soap:Header>" +


                _sr_body_hdr_ + "<snp:" + params.method + " xmlns:snp="" + ns + "">" + 


                params.toXml() + "</snp:" + params.method + "></soap:Body></soap:Envelope>";


    


    // send request


    params.xmlhttp = SOAPClient._getXmlHttp();


    params.xmlhttp.open("POST", params.svc, params.async);


    params.xmlhttp.setRequestHeader("SOAPAction", ""#"+params.method+""");    // SOAPAction: "#HelloWorld"


    params.xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");


    




    if(params.async)...{




        params.xmlhttp.onreadystatechange = function()...{


            if(params.xmlhttp.readyState == 4)


                SOAPClient._onSendSoapRequest(params);


        }


    }


    




    try...{


        params.xmlhttp.send(sr);


    }




    catch(ex)...{}


        


    if (!params.async)


        return SOAPClient._onSendSoapRequest(params);


}




SOAPClient._onSendSoapRequest = function(params)




...{




    if (params.xmlhttp.readyState == 4 && params.xmlhttp.status == 200)...{


        params.result = SOAP_SUCCESS;    // 未完...


        params.setToken();                // 设置全局变量: _soap_header_m_token_


    }


        


    if(params.async && params.callback)


        params.callback(params.result, params);


    


    if (!params.async)


        return params.result;


}




// private: utils


SOAPClient._getElementsByTagName = function(document, tagName, ns)




...{    




    try...{    


        // trying to get node omitting any namespaces (latest versions of MSXML.XMLDocument)


        var lst = document.selectNodes(".//*[local-name()=""+ tagName +""]");


        if (lst.length == 0)


            throw 0;


        return lst;


    }




    catch (ex)...{}


        


    // old XML parser support


    if (ns+"" == "undefined")


        return document.getElementsByTagName(tagName);


    


    return document.getElementsByTagName(ns+":"+tagName);    


}




SOAPClient._getService = function(wsdl)




...{


    var soap_address = SOAPClient._getElementsByTagName(wsdl.documentElement, "address", "soap").item(0);


    return SOAPClient._getAttribValue(soap_address, "location");


}




SOAPClient._getAttribValue = function(node, name)




...{


    return (node.attributes[name]+"" == "undefined") ? node.attributes.getNamedItem(name).nodeValue : node.attributes[name].value;


}




// private: xmlhttp factory


SOAPClient._getXmlHttp = function() 




...{




    try...{




        if(window.XMLHttpRequest)...{


            var req = new XMLHttpRequest();


            // some versions of Moz do not support the readyState property and the onreadystate event so we patch it!


            if(req.readyState == null) 




            ...{


                req.readyState = 1;


                req.addEventListener("load", 


                                    function() 




                                    ...{


                                        req.readyState = 4;


                                        if(typeof req.onreadystatechange == "function")


                                            req.onreadystatechange();


                                    },


                                    false);


            }


            return req;


        }




        else if(window.ActiveXObject) ...{


            return new ActiveXObject(SOAPClient._getXmlHttpProgID());


        }


    }




    catch (ex) ...{}


    


    throw new Error("Your browser does not support XmlHttp objects");


}




SOAPClient._getXmlHttpProgID = function()




...{


    if(SOAPClient._getXmlHttpProgID.progid)


        return SOAPClient._getXmlHttpProgID.progid;


    var progids = ["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];


    var o;


    for(var i = 0; i < progids.length; i++)




    ...{


        try




        ...{


            o = new ActiveXObject(progids[i]);


            return SOAPClient._getXmlHttpProgID.progid = progids[i];


        }




        catch (ex) ...{};


    }


    throw new Error("Could not find an installed XML parser");


}

假设ATL XML WebServices实现方法如下:


[id(1), helpstring("登入系统, 获得用户令牌和全图URL, 以后任何方法调用必须给出令牌")]




HRESULT login([in] BSTR Username, [in] BSTR Password);




id(2), helpstring("刷新地图, 取地图imgURL")]




HRESULT refresh([out] DOUBLE* Scale, [out, retval] BSTR *imgURL);



客户端IE中调用如下:


<HTML>


    <HEAD>


        <TITLE>WebGis Demo Page - WebGis AJAX Client</TITLE>


        <script language="javascript" src="ajax/soapclient.js"></script>


        <script language="javascript">


            // WebService URL


            var g_url = "http://cl2/mtkwebgis/MtkWebgis.dll?Handler=GenMtkWebgisWSDL";


                        


            function soap_callback(rcode, params)




            ...{


                if (rcode == SOAP_SUCCESS)




                ...{


                    switch (params.callid)




                    ...{


                    case "刷新":


                        imgMap.src = params.retval();                    // retval()    取得[out,retval]参数


                        alert( "当前比例:" + params.getval("Scale") );    // getval(...) 取得[out]参数


                        break;                    


                    }


                }


                else




                ...{


                    alert(params.callid+":发生错误");                    


                }                


            }


            


            function Login()




            ...{


                // 同步调用, 获得令牌 


                var soap = new SOAPParams("登录", g_url, "login", false);


                soap.add("Username", "cheung");


                soap.add("Password", "mine");


                if (SOAP_SUCCESS == SOAPClient.invoke(soap))


                    refresh();


                else


                    alert("登录失败");                    


            }


            


            function Refresh()




            ...{


                // 异步调用刷新, 默认回调函数soap_callback


                var soap = new SOAPParams("刷新", g_url, "refresh");


                SOAPClient.invoke(soap);


            }


        </script>


    </HEAD>


    <BODY onload="Login();">


        <div id="divMap"><img id="imgMap"></div>


    </BODY>


</HTML>

使用soapclient.js需要注意,我假设XML WebServices必须存在如上面所示的login方法,用于验证用户,而且m_token必须是soap头。login原型如下:


[ soap_method ]


[ soap_header( value = "m_token", out = true ) ]




HRESULT login(/**//*[in]*/ BSTR Username, /**//*[in]*/ BSTR Password)




...{        


    CHAR szID[MAX_TOKEN_LEN + 1];


    *szID = 0;




    DWORD dwSize = MAX_TOKEN_LEN;


    HRESULT hr =  m_spSessionSvc->CreateNewSession(szID, &dwSize, &m_spSession);


    CHECK_FAILED(hr);




    szID[dwSize] = 0;


    m_token = CComBSTR(szID).Detach();


            


    return hr;


}

这样,用户就可以通过soapclient.js在IE中直接调用ATL Server写的XML WebServices了。

(本文写于2006年9月,cheungmine,上海新区时空信息技术有限公司)

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐