• 开发DataSnapserver


    

    在上次的文章中讨论了怎样把传统的Delphi 主从架构应用程序逐渐转换为DataSnap JSONserver。在本篇文章中让我们正式讨论怎样使用Delphi XE开发DataSnap/RESTserver。因为这当中牵涉到许多的技术,因此我们将花数篇的篇幅来讨论。

    如今就让我们从DataSnap/RESTserver開始。

    开发DataSnapserver

        Delphi XE版的DataSnap同意开发者同一时候在DataSnapserver中实作RESTful架构的server,如此一来DataSnapserver不但能够在网络内 部做为多层的服务server,也能够让网络外部的client使用REST的方式来存取服务。 要在Delphi XE中建立DataSnap/RESTserver,请点选Files|New菜单,在DataSnap Server选项中选择DataSnap Server图像。例如以下图所看到的:

     

     

     

        Delphi XE提供三种不同的server型态。各自是以VCL应用程序实作的server,实作为主控程序的server以及实作成Windows服务应用程序的server。开发者可依据自己的需求选择建立适当的server型态。在本篇文章中让我们建立VCL应用程序型态的server:

     

     

        点选Nextbutton之后DataSnap精灵会例如以下图询问须要支持的通讯协议。是否使用安全验证功能以及是否要预先建立范例服务方法,让我们点选下方的Select All以选择建立全部的功能。例如以下图所看到的:

     

     

     

     

     

     

        点选Nextbutton,DataSnap精灵会例如以下图询问TCP/IPHTTP使用的通信埠,内定上TCP/IP使用211HTTP则使用 8080,开发者可依据自己的需求设定这两个通信埠,或是点选Find Open Portbutton让DataSnap精灵帮忙搜寻可使用的通信埠:

     

     

     

        接着DataSnap精灵会询问开发者实作服务方法的类别,开发者能够选择实作于TComponent类别,TDataModule类别或是TDSServerModule类别,在本文章中我们选择实作于TDSServerModule:

     

     

        点选Finishbutton之后,Delphi XE便会建立相相应的项目。我们开启ServerContainerUnit的话就能够看到当中包括了例如以下组件,当中的 TDSServerTDSTCPServerTransport以及TDSServerClass类别组件在Delphi 2010中就存在了,新的TDSHTTPService类别组件则提供了HTTP/HTTPS通讯协议的支持,而新的 TDSAuthenticationManager类别组件则提供安全验证功能,在稍后的文章中我们会说明怎样使用它。

     

     

     

     

     

        如今DataSnap精灵会在项目的ServerMethodsUnit程序单元中产生两个范例方法,EchoStringReverseString

    如今让我们在这个程序单元中增加一个新的服务方法『取得部落格文章名称』。例如以下所看到的:

    public

    { Public declarations }

    function EchoString(Value: string): string;

    function ReverseString(Value: string): string;

    function 取得部落格文章名称 : TJSONArray;

     

    接着实作『取得部落格文章名称』方法,例如以下所看到的:

    function TServerMethods2.取得部落格文章名称: TJSONArray;

    begin

    Result := TJSONArray.Create;

    Result.AddElement(TJSONString.Create(‘Delphi XE程序设计系列 1-主从架构, 多层到JSONREST’));

    Result.AddElement(TJSONString.Create(‘从原生APIREST API – 使用C++Builder XE开发REST应用程序’));

    Result.AddElement(TJSONString.Create(‘Delphi XE程序设计系列 2-DataSnap/RESTserver’));

    end;

     

        『取得部落格文章名称』方法建立TJSONArray对象,而且把三篇文章名称以TJSONString对象储存在元素中。最后回传TJSONArray对象给client。

     

        最后开启ServerMethodsUnit程序单元的设计接口,在当中放入dbExpress组件以存取储存在MS SQL Server数据库中的范例数据表FishFacts,稍后我们将说明这个DataSnap/RESTserver怎样同一时候以传统DataSnap的架构让用户端使用dbExpress组件存取数据。以及怎样以REST的架构让client存取它提供的服务。

     

     

     

     

        如今编译而且运行这个DataSnap/RESTserver。

        因为如今这个server同一时候可提供DataSnapRESTserver的功能。因此如今我们能够试着使用浏览器来使用存取这个server的服务。

    让我们使用以下的URI来呼叫『取得部落格文章名称』方法:

    http://localhost:8085/datasnap/rest/TServerMethods2/取得部落格文章名称

     

        我们能够在下图中看到,我们果然能够在浏览器中使用上面的URI成功的呼叫server的服务:

     

     

     

     

        并且我们从上图中能够清楚的看到回传的结果是使用JSON格式封装的JSON数组,每个数组元素是Unicode编码的JSON字符串

    连结使用DataSnapserver

        如今让我们建立一个clientVCL应用程序项目。放入TSQLConnection组件。然后设定它的特性值例如以下(此时DataSnap/RESTserver必须是在运行状态):

     

    特性

    特性值

    Driver

    Datasnap

    Connected

    True

     

     

        点选鼠标右键,选择建立『Generate DataSnap Client Classes』菜单,例如以下所看到的,再把产生的程序单元储存为ServerProxy程序单元。

     

     

     

     

    然后在主窗口中放入例如以下的dbExpressVCL组件:

     

     

     

     

    设定TDSProviderConnection组件的特性值例如以下:

     

    特性

    特性值

    SQLConnection

    SQLConnection1

    ServerClassName

    TServerMethods2

     

    再设定TClientDataSet的特性值例如以下:

    特性

    特性值

    RemoteServer

    DSProviderConnection1

    Provider

    dspFishFacts

     

     

        当我们在设定TClientDataSetProvider特性值时,client应用程序就会连结到DataSnap/RESTserver而且显示ServerMethodsUnit程序单元中输出的TDataSetProvider组件。

     

        让我们在『更新』button的OnClick事件处理函式中撰写例如以下的程序代码:

    procedure TForm10.Button3Click(Sender: TObject);

    begin

    if (cdsFishFacts.ChangeCount > 0) then

    cdsFishFacts.ApplyUpdates(0);

    end;

     

     

         编译而且运行client应用程序,我们就能够看到类似例如以下的画面:

     

     

     

     

        DataSnap/RESTserver就如同曾经的DataSnap/Midasserver一样能够提供二层和多层的开发架构,client应用程序也能够使用dbExpress组件来异动DataSnap/RESTserver中的数据。

    如今我们已经展示了这个DataSnap/RESTserver能够同一时候使用二层/多层和REST的架构来使用它。

    如今再让我们看看怎样在client使用程序代码来存取server的服务。在前面我们已经藉由TSQLConnection组件自己主动产生了ServerProxy程序单元,假设我们开启ServerProxy,便会看到以下的类别宣告:

     

    TServerMethods2Client = class(TDSAdminClient)

    private

    FEchoStringCommand: TDBXCommand;

    FReverseStringCommand: TDBXCommand;

    F取得部落格文章名称Command: TDBXCommand;

    public

    constructor Create(ADBXConnection: TDBXConnection); overload;

    constructor Create(ADBXConnection: TDBXConnection; AInstanceOwner: Boolean); overload;

    destructor Destroy; override;

    function EchoString(Value: string): string;

    function ReverseString(Value: string): string;

    function 取得部落格文章名称: TJSONArray;

    end;

     

    假设我们观察ServerProxy程序单元中的『取得部落格文章名称』方法,就能够看到它也使用dbExpress技术来存取server的服务:

    function TServerMethods2Client.取得部落格文章名称: TJSONArray;

    begin

    if F取得部落格文章名称Command = nil then

    begin

    F取得部落格文章名称Command := FDBXConnection.CreateCommand;

    F取得部落格文章名称Command.CommandType := TDBXCommandTypes.DSServerMethod;

    F取得部落格文章名称Command.Text := ‘TServerMethods2.取得部落格文章名称’;

    F取得部落格文章名称Command.Prepare;

    end;

    F取得部落格文章名称Command.ExecuteUpdate;

    Result := TJSONArray(F取得部落格文章名称Command.Parameters[0].Value.GetJSONValue(FInstanceOwner));

    end;

     

    因此在client。我们能够使用以下的程序代码藉由ServerProxy程序单元中的『取得部落格文章名称』方法来取得部落格文章信息:

     

    procedure TForm10.Button1Click(Sender: TObject);

    var

    aServer: TServerMethods2Client;

    ja : TJSONArray;

    iIndex: Integer;

    begin

    aServer := TServerMethods2Client.Create(Self.SQLConnection1.DBXConnection);

    try

    ja := aServer.取得部落格文章名称;

    for iIndex := 0 to ja.Size – 1 do

    ListBox1.Items.Add(ja.Get(iIndex).ToString);

    finally

    aServer.Free;

    end;

    end;

     

        下图是client应用程序运行上面程序代码的结果:

     

     

     

        可是除了dbExpress技术之外。我们也能够使用RESTJavaScript等技术来存取server服务,由于这个server就是一个RESTserver。因此让我们更深入的讨论一下怎样在client自己主动产生程序代码来支持RESTJavaScript等技术。

    client程序代码产生器

        DataSnap XE版眼下可自己主动产生四种client程序代码让不同的client可以连结和使用DataSnap/RESTserver。这四种是:

    DataSnap XE支持的四种client程序代码

    说明

    Delphi DBX

    使用dbExpress技术呼叫DataSnap/RESTserver的clientDelphi程序代码

    C++Builder DBX

    使用dbExpress技术呼叫DataSnap/RESTserver的clientC/C++程序代码

    Java Script REST

    使用REST/JSON技术呼叫DataSnap/RESTserver的clientJavaScript程序代码

    Delphi REST

    使用REST/JSON技术呼叫DataSnap/RESTserver的clientDelphi程序代码

     

     

     

     

        我们可以轻易的使用以下的程序代码来取得眼下可以产生的client程序代码:

     

     

    procedure TForm10.ListRegisteredWriter;

     

    var

    sa : TDBXStringArray;

    iIndex : Integer;

    begin

    sa := DSProxyWriter.TDSProxyWriterFactory.RegisteredWritersList;

    for iIndex := 0 to Length(sa) – 1 do

    ComboBox1.Items.Add(sa[iIndex]);

    ComboBox1.ItemIndex := 0;

    end;

     

     

        DSProxyWriter程序单元中 TDSProxyWriterFactory类别的类别方法RegisteredWritersList能够回传眼下注冊的client程序代码种类,眼下上表列出的四种client程序代码产生器分别位于DSProxyDelphiDSProxyCpp DSProxyJavaScriptDSProxyDelphiRest程序单元中。

     

     

     

        当我们要产生上表四种client程序代码以呼叫特定的DataSnap/RESTserver时,我们须要使用IDSProxyMetaDataLoader接口以及TDSProxyGenerator类别。

        IDSProxyMetaDataLoader接口是由TDSProxyMetaDataLoader类别实作的,我们能够使用 TDBXConnection对象建立TDSProxyMetaDataLoader对象。取得它的IDSProxyMetaDataLoader接口, 再建立TDSProxyGenerator对象。设定要产生的特定client程序代码目标。最后呼叫TDSProxyGenerator对象的Write方法, 如此一来DataSnap框架就会自己主动产生连结特定DataSnap/RESTserver的client程序代码。

        比如,如今让我们来看看怎样可以要求DataSnap框架自己主动产生Delphi REST或是JavaScript的client程序代码。

     

        以下的程序代码首先呼叫GetMetaDataLoader方法取得IDSProxyMetaDataLoader接口,再呼叫GenerateFile藉由IDSProxyMetaDataLoader接口产生使用者特定的client程序代码:

    procedure TForm10.Button2Click(Sender: TObject);

    var

    LMetaDataLoader: IDSProxyMetaDataLoader;

    begin

    LMetaDataLoader := GetMetaDataLoader;

    GenerateFile(LMetaDataLoader);

    ShowGeneratedFiles;

    end;

     

        GetMetaDataLoader方法藉由程序中的 TSQLConnectionTDBXConnection对象建立TDSProxyMetaDataLoader对象,再回传 TDSProxyMetaDataLoader对象实作的IDSProxyMetaDataLoader接口:

     

     

    function TForm10.GetMetaDataLoader : IDSProxyMetaDataLoader;

    begin

    Result := TDSProxyMetaDataLoader.Create(

    function: TDBXConnection

    begin

    OpenConnection;

    Result := SQLConnection1.DBXConnection;

    end,

    procedure(AConnection: TDBXConnection)

    begin

    SQLConnection1.Close;

    end

    );

    end;

     

     

        而GenerateFile方法先建立 TDSProxyGenerator对象,设定它的Writer特性值为稍后使用者在程序中设定的特定的client程序代码的名称。比如是『Delphi DBX』产生使用dbExpress技术的client程序代码,或是『Java Script REST』产生使用REST/JSONJavaScript程序代码,最后呼叫Write方法实际的产生client程序代码:

     

     

    procedure TForm10.GenerateFile(AMetaDataLoader: IDSProxyMetaDataLoader);

    var

    LProxyGenerator: TDSProxyGenerator;

    begin

    LProxyGenerator := TDSProxyGenerator.Create(nil);

    try

    LProxyGenerator.Writer := ComboBox1.Text;

    LProxyGenerator.TargetUnitName := ‘GeneratedServerProxy’;

    LProxyGenerator.ExcludeMethods := ;

    LProxyGenerator.ExcludeClasses := ;

    LProxyGenerator.TargetDirectory := ‘.’;

    LProxyGenerator.OnCreatingFiles := ACreatingFiles;

    LProxyGenerator.OnCreatedFiles := ACreatedFiles;

    LProxyGenerator.Write(AMetaDataLoader);

    finally

    LProxyGenerator.Free;

    end;

    end;

     

     

        如今假设我们运行client应用程序。能够看到例如以下的画面,在以下中我选择产生Delphi REST的client程序代码:

     

     

     

     

        那么这个范例client应用程序便会自己主动产生使用REST的clientDelphi程序代码,比如它产生的呼叫范例DataSnap/RESTserver的『取得部落格文章名称』方法的程序代码例如以下:

     

    function TServerMethods2Client.取得部落格文章名称(const ARequestFilter: string): TJSONArray;

    begin

    if F取得部落格文章名称Command = nil then

    begin

    F取得部落格文章名称Command := FConnection.CreateCommand;

    F取得部落格文章名称Command.RequestType := ‘GET’;

    F取得部落格文章名称Command.Text := ‘TServerMethods2.取得部落格文章名称’;

    F取得部落格文章名称Command.Prepare(TServerMethods2_取得部落格文章名称);

    end;

    F取得部落格文章名称Command.Execute(ARequestFilter);

    Result := TJSONArray(F取得部落格文章名称Command.Parameters[0].Value.GetJSONValue(FInstanceOwner));

    end;

     

     

        看到如今它是使用HTTPGet命令,藉由REST呼叫惯例来呼叫DataSnap/RESTserver的『取得部落格文章名称』方法了。

     

        假设我是选择产生Java Script REST

     

     

     

     

        那么以下就是DataSnap框架自己主动产生的clientJavaScript程序代码:

    /*

    * @return result – Type on server: TJSONArray

    */

    this.取得部落格文章名称 = function() {

    var returnObject = this.executor.executeMethod(‘取得部落格文章名称’, GET, [], arguments[0], true, arguments[1], arguments[2]);

    if (arguments[0] == null) {

    if (returnObject != null && returnObject.result != null && isArray(returnObject.result)) {

    var resultArray = returnObject.result;

    var resultObject = new Object();

    resultObject.result = resultArray[0];

    if (returnObject.cacheId != null && returnObject.cmdIndex != null) {

    resultObject._cacheId = returnObject.cacheId;

    resultObject._cmdIndex = returnObject.cmdIndex;

    }

    return resultObject;

    }

    return returnObject;

    }

    };

    this.取得部落格文章名称_URL = function() {

    return this.executor.getMethodURL(『取得部落格文章名称』, GET, [], arguments[0])[0];

    };

    }

    var JSProxyClassList = {

    TServerMethods2″: ["DSServerModuleCreate","DSServerModuleDestroy","EchoString","ReverseString","取得部落格文章名称"]

    };

     

     

     

     

        最后我试着同一时候使用Delphiclient应用程序以及浏览器两个不同的client来呼叫和使用范例DataSnap/RESTserver,看起来一切都很的美好:

     

     

     

     

     

        当然,我也能够使用纯粹的Webclient应用程序来呼叫和使用范例DataSnap/RESTserver。比例如以下图就是我使用VCL For Web XI来使用范例DataSnap/RESTserver的结果。全部的服务仍然工作良好:

     

     

     

     

     

     

     

        DataSnap XE版藉由扩充多层架构到RESTJSON的技术领域。让DataSnap XE瞬间突破了平台的限制。同意DelphiC/C++BuilderJavaScriptPHPRuby和移动设备等各种client可以使用它的服 务,再次赋予了DataSnap框架无限的发展潜能。

    好了,时间已晚,我们也下次再见了。

  • 相关阅读:
    SQLSERVER2008数据库增量备份还原方式
    使用VS2003遇到“无法显示进程。没有正确安装调试器。请运行安装程序安装或修复调试器。”的解决方法
    IIS7下配置最大上传附件大小需要注意的事项
    运行常用指令
    跨库查询推荐使用的方法
    获取客户端IP需要注意的一个问题
    如何判断一个表是否建立索引约束等信息的SQL语句
    SQLServer2005重建索引前后对比
    一个鼠标滚轮控制大小的缩放类。
    全兼容的纯CSS级联菜单
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/7100677.html
Copyright © 2020-2023  润新知