相关名词:
Dispatch: 派遣,分派 Invoke: 调用 Invokable: 可调用接口
TReomtable: WebService中自定义类都是继承自该类 TSOAPAttachment: Attachment:附件,一种流类型,可以返回流数据 CGI:(EXE)
ISAPI:(DLL) Base64编码: uses EncdDecd; s := EncodeString(s); //加 base64 编码 s := DecodeString( str ); //解码 UTF8: UTF8 是8位的UNICODE字符,而ASCII是7位 ,gb2312和unicode是2字节/字,utf8是3字节/字utf8类似以前的8位转7位的编码,是为 了 在网络间不同系统的通讯方便而作的转换。 几乎所有用.Net写的WebService只支持DOC方式、Delphi写的只支持RPC方式;J2ME目前对Web Service的支持仅限于RFC172,而 RFC172要求必须为DOC方式(sun怎么偏袒MS?)!
为了在设计中减少障碍,下面还介绍几个概念。
1) SOAP:SOAP是一种简单有效的数据传输协议,用于分布式网络环境下数据信息交换,它以XML 作为数据传输的格式,搭配Internet上标准的传输协议HTTP、SMTP、TCP等来传送信息。从本质上看,SOAP事实上只是将Request和 Response经由XML格式把数据打包,达到双方沟通的目的。
2) WSDL:WSDL(Web Service Description Language)是一种以XML格式描述的Web Service语言,当Web Service Provider 要对外公布提供的 Web Service,就需要通过WSDL来构建描述语言。 在WSDL中有两个非常重要的要素:
3):处理中文乱码的问题: 将HttpRio的 Converter 的 Options 的 soUTF8InHeader 设为 True 将生成soap消息的HTTPSoapDispatcher控件,添加encoding为gb2312 HTTPRIO.HTTPWebNode.UseUTF8InHeader := True;
4)在Delphi中,能够传递的自定义类型的对象要继承TRemotable,
5:修正一个服务器端的一个Bug:将ISAPIThreadPool和ISAPIApp的次序变一下:ISAPIApp必须在 ISAPIThreadPool之前: uses ... ISAPIApp, ISAPIThreadPool 解决如下错误: Received content of invalid Content-Type setting:text/html -SOAP"expects"text/xml" 6:"XML document must have a top level element. Line: 0" 错误,我该如何解决?? 哈纳斯 (2002-08-05 17:26:00) 我也曾碰到同样的问题 解决方法是:别设httprio的wsdllocation,设它的url 如http://localhost/mydir/project1.exe/wsdl/IFIRST mydir是你的可执行的虚拟目录,IFIRST是你定义的接口名 ***********************************************************************************************
Delphi中WebService包含的组件解释(有7个)
(1) THTTPRIO-------:使用Http消息来调用远程使用SOAP的接口对象
(2) THTTPReqResp---:给服务器发送一个SOAP消息, THTTPReqResp在可调用接口上执行一个方法请求.
(3) TOPToSoapDomConvert ----:TOPToSoapDomConvert处理Soap方法请求的组合与分发
(4) TSoapConnection:TSoapConnection在客户端的多层数据库应用中创建并维护客户端和作为WebService 的远程应用服务器间的连接
(5) THTTPSoapDispatcher -----:通过将Soap消息转发给调用者,THTTPSoapDispatcher对Soap消息做出响应.
(6) TWSDLHTMLPublish -----:TWSDLHTMLPublish发布描叙webService应用的Wsdl文档
(7) THTTPSoapPascalInvoker -----:THTTPSoapPascalInvoker解释Soap的请求信息,并执行相应的可调用接口. ***********************************************************************************************
WSDL 说明:
(Web Services Description Language) 规范是一个描述接口,语义以及Web服务为了响应请求需要经常处理的工作的XML文档。这将使 简单地服务方便,快速地被描述和记录。以下是一个WSDL的样例:
SOAP说明
(Simple Object Access Protocal)。 我们先简单了解WebServices运作模式。服务端生成服务描述文件WSDL(Web Services Description Language,类似COM的Interface Description Language),如果接收客户端的SOAP请求消息(XML格式数据),解析其调用和参数,根据WSDL和WSML(Web Services Meta Language,Microsoft为描述WSDL里提供的方法与实现该方法的COM对象之间的映射关系而特地设立),调用相应COM对象完成指定功 能,并返回 到SOAP消息遣至用户;客户端取得并解析服务端的服务描述文件从而得知服务端的服务内容及调用方式,生成SOAP请求消息(指定调用的方法 名称和参数)送往服务端。 ***********************************************************************************************
TReomtable说明
: WebService中自定义类都是继承自该类 //自己定义一个继承自TRemotable的类 (注意只有属性定义,没有方法) TSpeciesInfo = class(TRemotable) private FLength: Integer; FSpeciesName: string; FCategory: string; FCommonName: string; FmoreInfo: string; published property Category: string read FCategory write FCategory; property CommonName: string read FCommonName write FCommonName; property SpeciesName: string read FSpeciesName write FSpeciesName; property Length: Integer read FLength write FLength; property MoreInfo: string read FmoreInfo write FMoreInfo; end;
TSOAPAttachment说明
:一种Soap的流类型数据.跟平时的integer等等一个意思 //比如
(1):服务器端建立一个流输出(result:) GrapStream:=TMemoryStream.create; try SoapAttachment:=TSoapAttachment.create; TBolbField(frmdm.adoqury.fields[0]).SaveToStream(GrapStream); SoapAttachment.SetSourceStream(GraphStream,soReference); result:=SoapAttachment; except if assigned(GrapStream) then GrapStream.free; if assigned(SoapAttchament) then SoapAttchment.free; end
(2):客户端接受一个流输入 var src:string; begin if not Assigned(SoapAttachment) then exit; Src:=SoapAttachment.CacheFile; ....
例子,基于Soap和webService的分布式网络程序实例
//编写服务器端 --ok
1:File --->New---->Other----->WebService--->Soap WebService Application 后生成3个组件 一个是调用者组件:THTTPSoapPascalInvoker:完成Soap消息和.... 一个是调度者组件:THTTPSoapDispatcher:自动响应送入的soap消息,并且把他们传递给调用者,可以使用他的 WebDispatch属性来识别应用程序响应的http请求.包括设置PathInfo属性来指明指向应用 程序的任何URL的路径部分,设置MethodType属性来指明请求消息的方法头. 一个是WSDL发布者:TWSDLHTMLPublisher:WSDL发布者发布描叙接口以及如何调用他们的wsdl文档,使用非delphi 编写的客户端程序也可以调用WebService应用程序.
2:在接口中添加方法和在实现该接口的类中实现该方法. (1):接口中自定义的类都是继承自TRemotable类,该类只能有属性,没有方法 (2):
3:将生成的Dll文件拷贝到 C:"InetPub"Scripts目录下面.
//编写客户端 --ok
(1):File--->New--->other---->WebSerice--->Wsdl Importer: 对话框1:WsDl Source:输入==>http://服务器名/scripts/应用程序名/wsdl/相应接口 ,然后Next下步.然后点finish
(2):添加一个普通的窗体,上面放WebService中的控件:HTTPRIO,编写它的OnAfterExecute ,OnBeforeExecute事件 连接服务:http://server/script/MyWebService.dll/Soap/ImyWeb ***请注意是Soap/接口 FAttachService为WebService的接口 if FAttachService = nil then begin FAttachService := GetiMyWeb(False, EditUrl.Text); (FAttachService as IRIOAccess).RIO.OnBeforeExecute := HTTPRIO1BeforeExecute; (FAttachService as IRIOAccess).RIO.OnAfterExecute := HTTPRIO1AfterExecute; end; Result := FAttachService; ******************************************************************************* (HTTPRIO1 as ITest).TestFunction(aParam, bParam);
(3):注意在IIS中设置Script的是否有执行权限.
编写一个基于Soap DataModule的三层数据库应用
服务器端:
建立一个Web App Debugger executable类型,不需要接口,添加一个Soap Data Module,放上AdoCon,AdoDataSet,DataSetProvider1 设置数据好连接,利用AdoDataSet打开一个数据集,然后编译运行,打开Web App Debugger查看是否正确.
客户端:
(1)建立一个普通的应用程序,添加SoapConnection1组件,设置他的url:格式为:http://localhost:1024/Demo3.wadSoapDemo3/soap
(2)添加一个ClientDataSet 设置它的RemoteServer=SoapConnection1,provideName=DataSetProvider1 (注意将Web App Debugger打开) (3)Active就可以看到数据了.
WebService的服务器端的调试
(1):编写服务器时选择:Web App Debugger executable类型
(2):编写完成后运行一次服务器,则系统将把该webservice的类注册
(3):启动Tool--->Web App Debugger,设置servers的options port============1024 default url=====http://localhost:1024/Demo3.wadSoapDemo3/wsdl 其中demo3为exe程序的名字, wadSoapDemo3为建立服务器的时 候填写的类名称,可在主Form的initialization中找 到:TWebAppSockObjectFactory.Create('wadSoapDemo3')
(4)打开ie,在地址输入:http://localhost:1024/Demo3.wadSoapDemo3/wsdl就可以查看接口了