在发表RAD Studio柏林版介绍到DataSnap功能时,英巴的文件只说柏林版的DataSnap除了改bug之外,就是开始移除Indy并改用THTTPClient等新的HTTP相关类别, 另外又隐约提到一个类别TDBXJSONStream,它可使用在DataSnap服务方法中. 第1次看到TDBXJSONStream时感觉有点陌生,但从它的名称可大约猜出它应该是一个使用在dbExpress(DBX?)应用中的相关类别并提供JSON串行流的功能(JSONStream?).
嗯, 我很好奇的在IDE中搜寻TDBXJSONStream,并在Data.DBXCommon程序单元中找到了它, TDBXJSONStream是一个新类别,我并没有在以前的版本中看到它.查看它的程序代码发现它提供了JSON Reader和Writer, 那么这代表它提了写入JSON对象和读取JSON对象的功能.
property Reader: TJSONReader read GetJSONReader;
property Writer: TJSONWriter read GetJSONWriter;
此外它又有一个TStream对象特性, OK, 那么它一定可以在此TStream对象中写入和读出JSON对象, 而这些功能也正是它的名称代表的意义.
property BaseStream: TStream read FBaseStream;
了解了它的功能之后我们就可以来看看如何使用它. 先建立一个DataSnap Server项目, 在其中定义一个QueryHotel方法, 请注意QueryHotel方法回传的对象正是TDBXJSONStream:
function QueryHotel(const sName : String) : TDBXJSONStream;
此DataSnap Server项目使用FireDAC存取MS SQL Sevrer中的数据:
QueryHotel方法展示了如何使用TDBXJSONStream对象, 要写入JSON对象到TDBXJSONStream, 我们只需要使用它的Writer特性取得它的JSON Writer:
function TServerMethods1.QueryHotel(const sName: String): TDBXJSONStream;
var
sSQL : String;
procedure WritePair(const sProperty, sFieldName : String);
begin
Result.Writer.WritePropertyName(sProperty);
Result.Writer.WriteValue(qryTheHotel.FieldByName(sFieldName).AsString);
end;
begin
Result := TDBXJSONStream.Create;
sSQL := qryTheHotel.SQL.Text;
sSQL := sSQL + '''' + sName + '%''';
qryTheHotel.SQL.Text := sSQL;
qryTheHotel.Open();
try
Result.Writer.WriteStartArray;
while (not qryTheHotel.Eof) do
begin
try
Result.Writer.WriteStartObject;
WritePair('名称', 'STITLE');
WritePair('地址', 'ADDRESS');
WritePair('电话', 'MEMO_TEL');
finally
Result.Writer.WriteEndObject;
qryTheHotel.Next;
end;
end;
finally
Result.Writer.WriteEndArray;
Result.Writer.Close;
qryTheHotel.Close;
end;
end;
编译并执行此DataSnap Server之后就可以使用浏览器来试着呼叫QueryHotel方法, 下图显示成功的呼叫QueryHotel方法并取得由TDBXJSONStream对象回传的JSON数据:
当然我们也可以使用Windows/OSX/Android/iOS客户端来呼叫QueryHotel方法.
下面的显示了如何在客户端呼叫QueryHotel方法, 取得TDBXJSONStream对象并藉由TDBXJSONStream对象中的JSONReader对象读出在伺服端写入的JSON数据:
procedure TForm5.Button1Click(Sender: TObject);
var
aServer : TServerMethods1Client;
js : TDBXJSONStream;
begin
aServer := TServerMethods1Client.Create(Self.SQLConnection1.DBXConnection);
try
js := aServer.QueryHotel(Edit1.Text);
js.Reader.Rewind;
while (js.Reader.Read) do
begin
case js.Reader.TokenType of
TJsonToken.StartArray:
begin
while (js.Reader.Read) do
begin
case js.Reader.TokenType of
TJsonToken.PropertyName:
begin
ListView1.Items.Add.Text := js.Reader.Value.ToString + ' : ' + js.Reader.ReadAsString;
end;
end;
end;
end;
end;
end;
finally
aServer.Free;
end;
end;
执行客户端并开始查询资料就可以看到下面的结果画面:
那么为什么要使用TDBXJSONStream类别呢? 我想方便是主因, 因为它已经把数个功能结合在一个类别中, 免除程序员自己使用多个类别. 另外我在英巴文件中找到的数据说的是TDBXJSONStream类别速度很快. 嗯,我并没有去测试这个说明的真正的意义, 但它真的很好用就是了.
Have Fun!
Read More