C++ Builder 6 进行 SOAP 开发(2) -- 通过 SOAP 传递自定义类型数据

Web/WebService 专栏收录该内容
24 篇文章 0 订阅
C++ Builder 6 BizSnap/SOAP/WebService(2)
-- 通过 SOAP 传递自定义类型数据

    本文将做一个略复杂的例子,实现通过 SOAP 传递自定义的数据类型。本例子的功能是在服务端通过 dbExpress 的数据访问控件取得数据表内容,然后将其通过 SOAP 传递到客户端再显示。

    服务端:
1.New|WebServices|Soap Server Application ,如下图,与 Delphi 6 + Update 2 相比,除了左上角的图标以外,完全相同:

选 Web App Debugger executeable 类型, CoClass Name 为:wadSoapDemo2 ,如下图:

确定后将自动提示是否要新建一个接口,如下图,确定即可打开新建接口向导,如果要以后再增加接口,可以在 New|WebServices 中选择 SOAP Server Interface 同样可打开新建接口向导:

2.新建接口向导如下图,输入接口名:DataTable 即可生成一个 SOAP 服务端接口:

关于此向导的其它说明见《C++ Builder 6 BizSnap/SOAP/WebService(1) -- 一个 Hello world! 的例子》(以下简称《(1)》);
3.在生成后的 WebModule 单元中放入四个数据库控件: SQLConnection1, SQLDataSet1, DataSetProvider1, ClientDataSet1 ,其各属性设置如下表:

SQLConnection1ConnectionName = IBLocal;
LoginPrompt = false;
Params->Values["Database"] = "[...]//Examples//Database//Employee.gdb";
// 上面的 [...] 为你的 InterBase 安装路径
SQLDataSet1SQLConnection = SQLConnection1;
CommandText = "select FULL_NAME, PHONE_EXT";
DataSetProvider1DataSet = SQLDataSet1;
ClientDataSet1ProviderName = DataSetProvider1;

完成后的 WebModule 如下图:

4.SaveAll , Unit1 命名为: MainWM , Project1 命名为: Demo2 , DataTable 不改名;
5.在接口单元的头文件(DataTable.h)中增加一个自定义的类 -- TDataSetPack ,如下:

class TDataSetPack : public TRemotable {
private :
    int        FCount;
    AnsiString FXMLData;


public :
    __fastcall TDataSetPack( TClientDataSet * aClientDataSet )
        : TRemotable(),
        FCount( aClientDataSet->RecordCount ),
        FXMLData( aClientDataSet->XMLData )
    {
    }

__published:
    __property int        Count   = { read = FCount   }; 
    __property AnsiString XMLData = { read = FXMLData };
};

自定义 SOAP 数据类型必须是从 TRemotable 类派生的,这一点与 Delphi 相同。其中 ClientDataSet 的 XMLData 属性是从 Delphi 6 开始新增的。其实 XMLData 中已经包含了记录数信息, Count 属性并不是必须的,这里为了演示自定义 SOAP 数据类型的使用,所以加入这个属性。注意:要在此头文件中加入:#include <DBClient.hpp>
5.定义及实现 GetEmployeeTable 函数,其方法与《(1)》中相同,下面是在接口头文件(DataTable.h)和单元文件(DataTable.cpp)中的接口/类定义和我们加入的方法及其实现:

//  DataTable.h
__interface INTERFACE_UUID("{CF057C28-4130-4508-9F24-0BBD1C2CA5F0}") 
    IDataTable : public IInvokable
{
public:
    virtual TDataSetPack * GetEmployeeTable( void ) = 0;  //  新增方法
};
typedef DelphiInterface
     
       _di_IDataTable;

//  DataTable.cpp
class TDataTableImpl : public TInvokableClass, public IDataTable
{
public:
    TDataSetPack * GetEmployeeTable( void );  //  新增方法

  /* IUnknown */
  HRESULT STDMETHODCALLTYPE QueryInterface(const GUID& IID, void **Obj)
                        { return GetInterface(IID, Obj) ? S_OK : E_NOINTERFACE; }
  ULONG STDMETHODCALLTYPE AddRef() { return TInterfacedObject::_AddRef();  }
  ULONG STDMETHODCALLTYPE Release(){ return TInterfacedObject::_Release(); }

  /* Ensures that the class is not abstract */
  void checkValid() { delete new TDataTableImpl(); }
};

//  新增方法的实现:
//  打开 ClientDataSet ,构造 TDataSetPack ,
//  关闭 ClientDataSet 和数据库连接
//  返回结果
TDataSetPack * TDataTableImpl::GetEmployeeTable( void )
{
    WebModule2->ClientDataSet1->Open();
    TDataSetPack * p = new TDataSetPack( WebModule2->ClientDataSet1 );
    WebModule2->ClientDataSet1->Close();
    WebModule2->SQLConnection1->Close();
    return p;
}

     

除了方法的实现部分以外,其它部分与《(1)》基本上一样。这个方法的实现功能,正如程序中的注释说明的那样,用于取得数据集并转换为我们定义的数据类型后返回。
6.注册接口及其实现类的部分也与《(1)》相同,就不再赘述了。
7.编译之即可产生: Demo2.exe ;

先运行一次 Demo2.exe ,完成注册的工作后启动 Web App Debugger 。打开浏览器, 输入 URL 为: http://localhost:1024/Demo2.wadSoapDemo2 即可看到一个标准的 SOAP 应用说明页面,点击进入相应链接即可看到相关的 WSDL ,在其中可以看到我们自定义的数据类型说明,如下面的 WSDL 片断所示:

  <types>
    <xs:schema targetNamespace="urn:DataTable" xmlns="urn:DataTable">
      <xs:complexType name="TDataSetPack">
        <xs:sequence>
          <xs:element name="Count" type="xs:int"/>
          <xs:element name="XMLData" type="xs:string"/>
        </xs:sequence>
      </xs:complexType>
    </xs:schema>
  </types>

    客户端程序:
1.New|Application 新建一个一般 VCL 应用程序;
2.SaveAll , Unit1 命名为 ClnMain , Project1 命名为 Client ;
3.New|Web Services|Web Services Importer :
在下图中的URL中输入: http://localhost:1024/Demo2.wadSoapDemo2/wsdl/IDataTable,

如果上面用浏览器可以看到正确的 XML 文档的话,选择“Next”后将产生导入的结果,如下图:

其中有我们在服务端定义的数据类型 TDataSetPack 、接口 IDataTable 及其方法 GetEmployeeTable ,选择完成即可生成接口单元;
4.SaveAll, IDataTable 单元不改名保存,再在 ClnMain 中 #include IDataTable.h ;
5.在 Form 上放上一个 ClientDataSet, DataSource, DBGrid, Button, Label 等几个控件,其各属性设置如下表:

ClientDataSet1全部默认
DataSource1DataSet = ClientDataSet1;
DBGrid1DataSource = DataSource1;
Button1Caption = "Fetch data";
Label1Caption = "Count:0";

完成后的 Form 如下图:

6.双击 Button1 输入下面的程序:

void __fastcall TForm2::Button1Click(TObject *Sender)
{
    TDataSetPack * p = GetIDataTable()->GetEmployeeTable();

    Label1->Caption = AnsiString( "Count:" ) + IntToStr( p->Count );    
    ClientDataSet1->XMLData = p->XMLData;
}

7.编译运行,按 Button1 , DBGrid1 中将显示服务端返回的数据集内容, Label1 中将显示记录数,如下图;

    这只是一个简单的数据库访问的例子,只能从服务端取回数据集, C++ Builder 6 中已经将 MIDAS/DataSnap 和 SOAP/WebService 结合,可以通过 SOAP/WebService 实现非常强大的数据库操作能力,这将在以后的文章中介绍。

[Mental Studio]猛禽 Apr.30-02

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
含有全部工程文件,使用C++ Builder 6.0完成开发,可重新编译运行。创作权归曹润泽所有,使用者不可用于商业目的,否者后果自负。 本软件功能: 上层的应用软件的模块主要有:初始化模块、用户设置模块、COM串行通信数据采集模块、数据矫正模块、数据绘图模块、数据存储模块、网络传输模块、功能整合模块等。其中网络传输模块又可以根据工作模式分为服务端网络传输模块和客户端网络传输模块。 用户设置模块:主要是通过用户设置设置窗口中的信息来完成软件的设置,这些可以设置的变量都非常重要,包括基本设置:采样频率设置、COM端口选择、警告限设置(是否使用警戒限、高警戒限的大小、低警戒限的大小)、矫正表设置(是否使用矫正表、选择矫正表);绘图设置:显示点数设置、曲线宽度设置、曲线颜色设置(高警戒曲线的颜色、正常时曲线颜色、低警戒曲线的颜色设置);网络设置:是否使用网络传输、网络基本设置(服务端选择、客户端选择、端口号设置、服务端IP设置)。 COM串行通信数据采集模块:用于从串行口中读取数据。 本系统使用专门用于RS-232串行通信通信控制的控件TComm控件来完成COM通信。 数据矫正模块,顾名思义,是用于对数据进行矫正的。若需要矫正数据,必须使用矫正表,矫正表实际上只是个用户可自定义的文本文件,但在编写矫正表文件时必须按照一定规则进行编写。 数据绘图模块:对于采集数据的实时绘图是通过Borland C++ Builder 6.0自带的功能强大的TChart控件来实现。 数据存储模块:该模块除了使用了编译器所提供的几个基本数据类型之外,基本上是使用纯C++编写(不使用编译器的控件)。数据存储并未使用数据库存储,而是使用文本文件的方式对所有采集到的时间进行存储,存储时要先把采样信息写入到数据文件的头部,包括创建时间、采样起始时间、采样持续时间、采样结束时间、采样频率、采样数等等信息,之后就是所采集的数据,采样数据包括数值和采集的该点所对应的时间,以及该点是否被警告(过低用!Low表示、正常用-表示、过高用!High表示)。 网络传输模块:网络传输模块是本数据采集系统比较新颖的模块,可以使用互联网进行速率较低的数据传输,考虑到网络传输的延迟,故设计时设置的采样速率比较低。网络传输模块实际上是使用Socket编程实现的,在Borland C++ Builder中有封装好的用于网络通信的控件:TServerSocket和TClientSocket。
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值