XML SOAP应用简介

发表于:2007-07-01来源:作者:点击数: 标签:
如果想了解SOAP到底是什么,就要自己动手建立自己的SOAP标准对象。本文可以帮助你起步。 简介 SOAP - 简单对象处理协议(Simple Object Access Protocol) - 是当前XML 开发 的热点。它是微软新一代Visual Studio的主要角色,是.NET策略的基


如果想了解SOAP到底是什么,就要自己动手建立自己的SOAP标准对象。本文可以帮助你起步。

简介
SOAP - 简单对象处理协议(Simple Object Aclearcase/" target="_blank" >ccess Protocol) - 是当前XML开发的热点。它是微软新一代Visual Studio的主要角色,是".NET"策略的基础。如果想用VB 6编制一个有保障的SOAP服务,可以查阅微软的SOAP工具包(VB)。但如果想了解SOAP到底是什么,就要自己动手建立自己的SOAP标准对象。本文可以帮助你起步。

本文中,我们创建一个简单的SOAP服务端和一个客户端。服务端用ASP编写,名为soap.asp。这个文件应存放在个人Web服务器的根目录下,如:\.netpub\wwwroot。这个服务器将接受和处理客户端提出的SOAP请求。客户端是一个简单的VB可执行文件,由Sub Main()启动。

步骤
众所周知,SOAP是一个“呼叫-响应”机制,按客户/服务方式运行。客户端(应用程序)向服务端(位于互联网上的某个Web服务器)发出函数调用请求并传递参数;服务端则返回响应。呼叫与响应的内容和数据都是按XML文件格式进行传送的。因此,要建立一个简单的SOAP应用系统,就要建立一个客户端和一个服务端,即一个呼叫-响应体系。

下面是一个简单例子:
我们建立一个服务端来计算销售交易的税款。按照传统的VB术语,即建立一个函数,定义如下:
   Public Function GetSalesTax(ByVal pSalesTotal As Double) as Double
     GetSalesTax = pSalesTotal * 0.04
   End Function

一个粗糙的函数,但可作为示例(本例只能用于税率为4%的地方)。
这个函数定义了一个函数名(GetSalesTax),一个参数(pSalesTotal – 销售金额)和一个返回值(函数返回值)。按照面向对象原则,可以认为pSalesTotal是一个"IN"参数,GetSalesTax返回值是一个"OUT"参数。因此我们的SOAP服务端就要侦听客户发出的调用GetSalesTax的请求和传递的"IN"参数(销售金额),然后返回带有"OUT"参数的回应,向客户返回所需税款。

客户端
下面是用VB建立一个呼叫服务的客户端程序:
   dblSalesTax = GetSalesTax(100)
   得到返回值$4。
   
   如果GetSalesTax函数是一个外部对象,比如在MTS服务器上,就要调用服务器上的DLL模块:
   Dim objTax As New CTaxCalc
   dblSalesTax = objTax.GetSalesTax(100)

在SOAP系统中,远程调用的方式略有不同,呼叫是通过XML文件传送到服务器的。XML文件里有调用的函数名和相应的参数:
   <GetSalesTax>
     <SalesTotal>100</SalesTotal>
   <GetSalesTax>

为确保服务器能够识别和解释客户请求,呼叫指令被包装到一个称之为SOAP信封的大文件里。这个信封使用的是SOAP封装标准的通用命名空间:
   <SOAP:Envelope xmlns:SOAP="urn:schemas-xmlsoap-org:soap.v1">
     <SOAP:Header></SOAP:Header>
     <SOAP:Body>
       <GetSalesTax>
         <SalesTotal>100</SalesTotal>
       <GetSalesTax>
     </SOAP:Body>
   </SOAP:Envelope>

最后,加入函数调用的命名空间,起到函数声明的作用:
   <SOAP:Envelope xmlns:SOAP="urn:schemas-xmlsoap-org:soap.v1">
     <SOAP:Header></SOAP:Header>
     <SOAP:Body>
       <m:GetSalesTax xmlns:m="urn:myserver/soap:TaxCalc">
         <SalesTotal>100</SalesTotal>
       </m:GetSalesTax>
     </SOAP:Body>
   </SOAP:Envelope>

现在,已经准备好客户请求文件,可以送往服务端了。发送请求很简单,可以跟浏览器表单一样,用HTTP post方式。浏览器可以向服务端发送复杂的表单,.NET可以向服务器发送VB代码,但我使用XMLHTTP(IE 5以上版本才能用)。

假设strEnvelope含有XML文件格式的请求,发送格式如下:
   Dim objHTTP As New MSXML.XMLHTTPRequest
   Dim strEnvelope As String

   @#设定发往本地服务器
   objHTTP.open "post", "http://localhost/soap/soap.asp"

   @#设定标准SOAP/ XML文件头格式
   objHTTP.setRequestHeader "Content-Type", "text/xml"

   @#设置呼叫函数请求
   objHTTP.setRequestHeader "SOAPMethodName", _
     "urn:myserver/soap:TaxCalc#GetSalesTax"

   @#呼叫SOAP
   objHTTP.send strEnvelope

   @#取得返回值
   strReturn = objHTTP.responseBody

至此,客户端完成了向服务端发送请求的过程。现在回到服务端,看看服务端如何侦听客户请求并作出响应。

服务端
服务端要能够接收客户发出的HTTP请求,在本地服务器(http://localhost/soap.asp)接收到客户请求时作出回应。因此服务端要能够解析客户端发出的XML格式(SOAP封装)的请求,取出调用的函数名和参数。

服务端文件是soap.asp,它接收客户请求的做法是:
   Set objReq = Server.CreateObject("Microsoft.XMLDOM")
   objReq.Load Request

然后用XSL样式从封装的XML文件中取出参数:
   strQuery = "SOAP:Envelope/SOAP:Body/m:GetSalesTax/SalesTotal"
   varSalesTotal = objReq.SelectSingleNode(strQuery).Text

根据参数计算税款:
   varSalesTax = varSalesTotal * 0.04

在将结果返回给客户之前,要按SOAP标准做格式化封装。过程与客户端类似,只是把"IN"参数改换为"OUT"参数,并将函数标记名标为回应:
   <SOAP:Envelope xmlns:SOAP="urn:schemas-xmlsoap-org:soap.v1">
     <SOAP:Header></SOAP:Header>
     <SOAP:Body>
      <m:GetSalesTaxResponse xmlns:m="urn:myserver/soap:TaxCalc">
        <SalesTax>4</SalesTax>
      </m:GetSalesTaxResponse>
     </SOAP:Body>
   </SOAP:Envelope>

可以用字符串方式构造这个回应文件,也可以创建一个DOM对象,增加一个节点。
文件返回给客户后,客户经过解码就能得到结果:
   Dim objReturn As New MSXML.DomDocument
   objReturn.LoadXML strReturn
   strQuery = _
    "SOAP:Envelope/SOAP:Body/m:GetSalesTaxResponse/SalesTax"
   dblTax = objReturn.SelectSingleNode(strQuery).Text

这样就完成了一个简单的SOAP服务应用。虽然Visual Studio 7掩盖了内在的SOAP协议,但我希望本文有助于理解SOAP的操作过程。

下面是客户端VB代码:
   VB Client Code
   Sub Main()
    Dim objHTTP As New MSXML.XMLHTTPRequest
    Dim strEnvelope As String
    Dim strReturn As String
    Dim objReturn As New MSXML.DOMDocument
    Dim dblTax As Double
    Dim strQuery As String
    
    @#创建SOAP封装
    strEnvelope = _
     "<soap:envelope xmlns:soap=""urn:schemas-xmlsoap-org:soap.v1"">" & _
     "<soap:header></soap:header>" & _
     "<soap:body>" & _
     "<m:getsalestax xmlns:m=""urn:myserver/soap:TaxCalculator"">" & _
     "<salestotal>100</salestotal>" & _
     "</m:getsalestax>" & _
     "</soap:body>" & _
     "</soap:envelope>"
    
    @#设定发往本地服务器
    objHTTP.open "post", "http://localhost/soap.asp", False
    
    @#设定标准SOAP/ XML格式
    objHTTP.setRequestHeader "Content-Type", "text/xml"
    
    @#设置调用函数头
    objHTTP.setRequestHeader "SOAPMethodName", _
     "urn:myserver/soap:TaxCalculator#GetSalesTax"
    
    @#SOAP呼叫
    objHTTP.send strEnvelope
    
    @#取出返回信封
    strReturn = objHTTP.responseText
    
    @#加载到DOM
    objReturn.loadXML strReturn
    
    @#查询返回值
    strQuery = _
     "SOAP:Envelope/SOAP:Body/m:GetSalesTaxResponse/SalesTax"
    dblTax = objReturn.selectSingleNode(strQuery).Text
    
    Debug.Print dblTax
   End Sub
  
  
   下面是服务端ASP代码(文件名soap.asp,存放在本地服务器根目录下):
   <%
   Set objReq = Server.CreateObject("Microsoft.XMLDOM")

   @#加载请求到XML DOM
   objReq.Load Request

   @#按照输入参数查询
   strQuery = "SOAP:Envelope/SOAP:Body/m:GetSalesTax/SalesTotal"
   varSalesTotal = objReq.SelectSingleNode(strQuery).Text

   @#计算
   varSalesTax = varSalesTotal * 0.04

   @#准备返回信封
   strTmp = _
   "<soap:envelope xmlns:soap=""urn:schemas-xmlsoap-org:soap.v1"">" & _
   "<soap:header></soap:header>" & _
   "<soap:body>" & _
   "<m:getsalestaxresponse xmlns:m=""urn:myserver/soap:TaxCalc"">" & _
   "<salestax>" & varSalesTax & "</salestax>" & _
   "</m:getsalestaxresponse>" & _
   "</soap:body>" & _
   "</soap:envelope>"

   @#回写结果文件
   Response.Write strTmp
   %>

原文转自:http://www.ltesting.net