Delphi XE程序设计系列 1-主从架构, 多层到JSON和REST

2024-02-03 08:40

本文主要是介绍Delphi XE程序设计系列 1-主从架构, 多层到JSON和REST,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

从桌面开发,主从架构,一直到多层架构,虽然都是广泛被接受的观念和技术,但在信息技术的实作上却从不是开放, 相容的世界。Delphi从桌面开发到主从架构都是使用自己的数据传递格式以及通讯传递架构,到了多层架构虽然使用了Windows平台上的通讯协议,例 如COM/DCOM/COM+,但是在传递的数据格式方面仍然是使用自己的架构,COM/DCOM/COM+也是MS专属的通讯协议,和其它平台上使用的 通讯协议也不一样。当然,不光是Delphi/BCB,大部份的开发工具也是采用类似的方式,那就是都支持桌面开发,主从架构或是多层架构等通用观念的架 构,但使用来传递数据和沟通通讯协议都是封闭的架构。

直到JSONREST的出现以及Delphi/BCB确定走向原生,跨平台的道路之后,Delphi/BCB 2010版便开始走向以JSON封装数据,以REST做为通讯架构的方向。因此Delphi/BCB除了仍然支持原有的数据封装格式以及通讯协议之外,也允许开发人员选择使用JSONREST,使用JSONREST的好处是除了可以让JSONREST拥抱最新的信息技术之外,也可以让 Delphi/BCB在不同的平台中使用相同的技术来开发主从架构,分布式多层以及Web应用,也可以更容易的和其它的程序语言,框架和技术整合在一起。

现在让我们重温旧梦一下,看看如何把一个简单的主从架构应用程序转换为使用JSON的架构。

主从架构

下图是一个简单的主从架构的主窗体,

它藉由下图的dbExpress组件从数据库的FishFacts数据表中取得数据,并且使用数据感知组件显示在应用程序的主窗体中。

虽然从BDEdbExpress都使用专属的格式封装资料,但BDEdbExpress也可以把数据封装成较开放的XML格式,因此要把上图中TClientDataSet中的数据转换为XML的格式,我们只需要存取它的XMLData特性值即可:

dssmFishFact.cdsFishFact.XMLData;

XMLData特性值会回传以下面格式封装的XML数据:

<?xml version=1.0″ encoding=UTF-8″ standalone=yes?> <DATAPACKET Version=2.0″><METADATA><FIELDS><FIELD attrname=Category fieldtype=string WIDTH=15″/><FIELD fieldname=Species Name attrname=Species_Name fieldtype=string WIDTH=40″/><FIELD fieldname=Length (cm) attrname=Length__cm_ fieldtype=r8″/><FIELD attrname=Length_In fieldtype=r8″/><FIELD attrname=Common_Name fieldtype=string WIDTH=30″/><FIELD attrname=Notes fieldtype=string WIDTH=50″/><FIELD attrname=Graphic fieldtype=bin.hex SUBTYPE=Binary WIDTH=1″/><FIELD fieldname=Species No attrname=Species_No fieldtype=r8″/></FIELDS><PARAMS LCID=0″/></METADATA><ROWDATA><ROW Category=Triggerfish Species_Name=Ballistoides conspicillum Length__cm_=50″ Length_In=19.68503937007874″ Common_Name=Clown Triggerfish Notes=Also known as the big spotted triggerfish. Inhabi

然而BDE/dbExpress虽然能够把数据封装成XML格式,但使用XML封装数据时仍然会因为不同的数据存取使用不同的XML元素来封装资 料,因此在交换数据时仍然会造成许多的困扰,而且使用XML格式封装数据的成本比起JSON来要昂贵许多(XML使用较多元素,较为复杂的规则封装数据所 致)

因此Delphi/BCB要支持JSON/REST技术,其中一个工作就是必须能够把数据封装成JSON的格式,因此从Delphi/BCB 2010版开始便在VCLRTL中加入了许多和JSON相关的类别以执行这项工作。到了XEDelphi/BCB基本上不但能够把数据封装成JSON 的格式,甚至提供了RESTAPI允许DelphiBCB和任何支持JSONREST的客户端和使用Delphi/BCB开发的DataSnap伺 服器整合在一起,下图叙述了Delphi/BCB XE版支持的架构:

OK,现在先让我们看看Delphi/BCB XE如何能够把数据封装成JSON的格式,以及提供解析,处理JSON封包的相关类别。稍后我们再讨论Delphi/BCB XE如何支持REST API的使用和呼叫。

其实要把dbExpress中的数据封装成JSON非常的简单,就以直觉来说,我们只需要一个单向,只读的数据集,这个单向,只读的资料集可以直接从dbExpress的数据集组件建立,接着再一一的从这个单向,只读的数据集中读取数据,根据JSON规则封装即可。

因此在VCL中提供了TDBXDataSetReader这个单向,只读的资料集,它可以从dbExpress数据集组件建立,接着在TDBXJSONTools类别中提供了TableToJSON类别方法,它接受一个TDBXReader对象为第一个参数,第二个参数为要从第一个参数中封装的记录笔数,最后一个参数则代表在TableToJSON执行完毕之后是否需要释放第一个参数对象:

class function TableToJSON(const Value: TDBXReader; const RowCount: Integer; const IsLocalConnection: Boolean): TJSONObject; static;

因此要封装范例FishFacts数据表中的2笔资料为JSON格式,我们就可以使用下面的程序代码来完成这个工作。

在下面的程序代码中我们首先藉由数据模块中的TClientDataSet组件建立TDBXDataSetReader组件,接着呼叫TDBXJSONTools类别的TableToJSON类别方法把数据封装成JSON格式:

procedure TForm1.btnToJSONClick(Sender: TObject);

var

aDBXReader : TDBXReader;

aJSonObj : TJSONObject;

begin

aDBXReader := TDBXDataSetReader.Create(dssmFishFact.cdsFishFact, False);

try

aJSonObj := TDBXJSONTools.TableToJSON(aDBXReader, 2, False);

Memo2.Lines.Text := aJSonObj.ToString;

ParseData(aJSonObj);

finally

aJSonObj.Free;

aDBXReader.Free;

end;

end;

下图是执行

dssmFishFact.cdsFishFact.XMLData;

之后得到的XML格式的结果:

而下图则是藉由TableToJSON转换为JSON格式的结果:

如果我们观察JSON格式的结果可以看到DataSnap是以JSON对象封装数据,而每一个字段则是以JSON数组来封装:

{table:[["Category",1,0,0,15,16,0,0,false,false,0,false,false],["Species Name",1,1,0,40,41,0,0,false,false,0,false,false]….

由于使用JSON格式封装数据比较简单而且在解析上也比XML容易,我们可以使用VCLJSON相关的类别很容易的解析出其中封装的数据。例如下面的ParseData从前面TableToJSON建立的JSON对象中解析其中封装的FishFacts数据表的数据:

procedure TForm1.ParseData(aJSONObj: TJSONObject);

var

iPair : Integer;

aPair : TJSONPair;

begin

for iPair := 0 to aJSONObj.Size – 1 do

begin

aPair := aJSONObj.Get(iPair);

if (aPair.JsonString.ToString <> ‘Graphic‘) then

Memo3.Lines.Add(Format(‘%s : %s’, [aPair.JsonString.ToString, aPair.JsonValue.ToString]));

end;

end;

下图即是ParseData执行后的结果:

由于DataSnap可以使用JSON封装数据,因此任何支持JSON的程序语言或是框架都可以处理DataSnap封装的数据,这也代表任何支持JSON的客户端都可以连结到Delphi/BCB XE建立的DataSnap JSON服务器并且呼叫它提供的服务。

OK,现在我们了解了如何使用DataSnap封装数据为JSON格式,因此我们现在可以很容易的把这个传统的主从架构应用程序转换为DataSnap JSON服务器,如此一来我们就提供了如何把传统主从架构架逐渐构转换为分布式JSON架构的可能性。

我们的第一步是把这个主从架构应用程序转换为DataSnap JSON服务器,要如此做我们需要让这个主从架构把数据以JSON的格式输出,以便客户端能够存取,使用。

转换主从架构应用程序为DataSnap JSON服务器

为了输出主从架构应用程序的数据,让我们首先在这个主从架构项目中建立一个Server Module,如下所示。Server Module能够自动把包含它的应用程序的数据或是服务输出给客户端使用。

由于我们现在需要把主从架构应用程序中的数据输出以便让客户端应用程序能够存取,因此我们需要把原本主从架构中数据模块中的dbExpress相关组件移动这个建立的Server Module中,接着在原本主从架构的数据模块中加入TDSServerTDSTCPServerTransportTDSServerClass组件,如下所示:

接着在TDSServerClass组件的GetClass事件处理函式中设定它的PersistentClass参数为Server Module中的TClientDataSet组件类别:

procedure TdmFishFact.dsscFishFactGetClass(DSServerClass: TDSServerClass;

var PersistentClass: TPersistentClass);

begin

PersistentClass := usmFishFact.TdssmFishFact;

end;

完成了这个简单的工作之后,现在如果我们编译并且再次执行这个主从架构应用程序,那么现在它不但仍然可以做为传统主从架构应用程序来使用,它现在也已经成为了一个DataSnap JSON服务器,现在我们就可以建立一个DataSnap客户端来连结它并且取得FishFacts的资料。

建立Delphi DataSnap客户端

建立一个VCL Form应用程序项目,在主窗体中加入如下的组件:

要连结前面的范例DataSnap服务器,我们只需要加入TSQLConnection组件,并且设定它的特性如下:

特性

特性值

Driver

Datasnap

加入一个TDSProviderConnection组件,设定它的特性值如下:

特性

特性值

SQLConnection

SQLConnection1

ServerClassName

TdssmFishFact

Name

DSPCFishFact

加入一个TClientDataSet组件,设定它的特性值如下:

特性

特性值

RemoteServer

DSPCFishFact

ProviderName

dspFishFact

在上面的设定中关键的两个设定是TDSProviderConnection组件的ServerClassName特性值必须设定为DataSnap服务器中Server Module的类别名称,以及TClientDataSet组件的ProviderName必须设定为Server Module中的TDataSetProvider组件。而在这个范例DataSnap服务器中的Server Module的类别名称就是TdssmFishFact,而Server Module中的TDataSetProvider组件名称则是dspFishFact

下图就是设定TDSProviderConnection组件画面:

而下面则是设定TClientDataSet组件的对象检视器:

设定好了之后只要再连结相关的数据感知组件就可以完成客户端应用程序了。

现在如果我们执行范例主从架构应用程序兼DataSnap服务器,再执行DataSnap客户端应用程序,那么我们可以看到类似下面的画面:

上图中范例主从架构应用程序兼DataSnap服务器执行时既是传统的主从架构,也是DataSnap服务器,因此右下方的DataSnap客户端应用程序执行之后才能够从这个主从架构应用程序兼DataSnap服务器取得FishFacts数据。

如何? 了解了dbExpress/DataSnap如何使用JSON封装数据的原理之后我们就可以容易的把它转换为DataSnap服务器。读者可以使用类似的方式在保留主从架构架构的同时又逐渐的把主从架构转换为DataSnap的分布式JSON架构。

我们下次再谈谈Delphi如何支持REST API,如此一来我们就可以让其它的JSON客户端连结并且使用DelphiDataSnap JSON服务器提供的服务,再见了。

转载于:https://www.cnblogs.com/MaxWoods/archive/2011/08/11/2135564.html

这篇关于Delphi XE程序设计系列 1-主从架构, 多层到JSON和REST的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/673582

相关文章

java中判断json key是否存在的几种方法

《java中判断jsonkey是否存在的几种方法》在使用Java处理JSON数据时,如何判断某一个key是否存在?本文就来介绍三种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目http://www.chinasem.cn录第一种方法是使用 jsONObject 的 has 方法

Spring Boot分层架构详解之从Controller到Service再到Mapper的完整流程(用户管理系统为例)

《SpringBoot分层架构详解之从Controller到Service再到Mapper的完整流程(用户管理系统为例)》本文将以一个实际案例(用户管理系统)为例,详细解析SpringBoot中Co... 目录引言:为什么学习Spring Boot分层架构?第一部分:Spring Boot的整体架构1.1

Go语言中json操作的实现

《Go语言中json操作的实现》本文主要介绍了Go语言中的json操作的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录 一、jsOChina编程N 与 Go 类型对应关系️ 二、基本操作:编码与解码 三、结构体标签(Struc

Vue3 如何通过json配置生成查询表单

《Vue3如何通过json配置生成查询表单》本文给大家介绍Vue3如何通过json配置生成查询表单,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录功能实现背景项目代码案例功能实现背景通过vue3实现后台管理项目一定含有表格功能,通常离不开表单

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本

C#下Newtonsoft.Json的具体使用

《C#下Newtonsoft.Json的具体使用》Newtonsoft.Json是一个非常流行的C#JSON序列化和反序列化库,它可以方便地将C#对象转换为JSON格式,或者将JSON数据解析为C#对... 目录安装 Newtonsoft.json基本用法1. 序列化 C# 对象为 JSON2. 反序列化

Python中Json和其他类型相互转换的实现示例

《Python中Json和其他类型相互转换的实现示例》本文介绍了在Python中使用json模块实现json数据与dict、object之间的高效转换,包括loads(),load(),dumps()... 项目中经常会用到json格式转为object对象、dict字典格式等。在此做个记录,方便后续用到该方

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映

Python进行JSON和Excel文件转换处理指南

《Python进行JSON和Excel文件转换处理指南》在数据交换与系统集成中,JSON与Excel是两种极为常见的数据格式,本文将介绍如何使用Python实现将JSON转换为格式化的Excel文件,... 目录将 jsON 导入为格式化 Excel将 Excel 导出为结构化 JSON处理嵌套 JSON:

详解MySQL中JSON数据类型用法及与传统JSON字符串对比

《详解MySQL中JSON数据类型用法及与传统JSON字符串对比》MySQL从5.7版本开始引入了JSON数据类型,专门用于存储JSON格式的数据,本文将为大家简单介绍一下MySQL中JSON数据类型... 目录前言基本用法jsON数据类型 vs 传统JSON字符串1. 存储方式2. 查询方式对比3. 索引