準備使用DELPHI開發移動設備開發的朋友對DATASNAP REST中間件不可不瞭解。程序員
DATASNAP REST新型WEBSERVICES中間件使用的通訊協議和數據封裝格式:sql
使用HTTP通訊協議,HTTP協議哪一個平臺都支持;使用JSON做爲數據的封裝格式,幾乎全部的開發語言均可以解析JSON數據。api
REST的目的就是經過簡單的URL來完成對中間層遠程方法的調用並返回JSON格式的數據,調用方解析JSON數據而後將數據秀出來。編碼
正是基於以上緣由,DATASNAP REST中間件才能夠爲蘋果和安卓的移動的NATIVE APP提供數據服務;也能夠爲WINDOWS、LINUX、MAC等url
桌面型NATIVE APP提供數據服務。rest
下面筆者將對跨平臺做出演示:orm
1.根據DELPHI的嚮導生成DATASNAP REST中間件(略過)。中間件
2.在中間件遠程方法裏面增長一個方法:blog
function TServerMethods1.GetData(sql: string): tdataset;
begin
q.close;
q.sql.clear;
q.sql.text := sql;
q.Open;
Result:= q;
end;開發
3.客戶端調用,由於演示跨平臺的緣由,此處只介紹經過URL調用中間件的方法。
procedure TForm1.Button1Click(Sender: TObject);
var
s:string;
jo: ISuperObject;
ja, jb, jc: TSuperArray;
i, h: Integer;
FieldList: TStringList;
arr: array of array of string;
begin
Memo1.Clear;
FieldList:= TStringList.Create;
try
s := idhttp1.Get('http://localhost:8080/datasnap/rest/TServerMethods1/GetData/select * from t1 where iid=''2''');
Memo1.Lines.add(s);
jo := so(s);
ja := jo['result'].AsArray;
// 獲取字段列表
jb := ja[0]['table'].AsArray;
for i := 0 to jb.Length-1 do begin
jc := jb[i].AsArray;
FieldList.Add(jc[0].AsString)
end;
// 數據集建立字段
cds.close;
cds.FieldDefs.Clear;
for i := 0 to fieldList.Count -1 do begin
CDS.FieldDefs.Add(fieldList[i],ftString,100, False);
end;
CDS.CreateDataSet;
// 設置表格的列寬
for i := 0 to dbgrid1.Columns.Count-1 do begin
DBGrid1.Columns[i].width := 80;
end;
// 數據集填充數據
SetLength(arr, ja[0][FieldList[0]].AsArray.Length, FieldList.Count);
for i := 0 to fieldlist.count-1 do begin // col
jb := ja[0][FieldList[i]].AsArray;
for h := 0 to jb.Length-1 do begin // row
arr[h, i] := jb[h].AsString;
end;
end;
cds.DisableControls; try
for i := 0 to jb.Length-1 do begin // row
cds.Append;
for h := 0 to fieldlist.count-1 do begin // col
cds.Fields[h].Value := arr[i, h];
end;
cds.Post;
end;
finally
cds.EnableControls;
end;
finally
FieldList.Free;
end;
end;
幾乎全部的開發語言都支持經過HTTP GET,而後解析中間件返回的JSON數據。具體代碼由各開發語言的程序員編寫,此處
只介紹DELPHI如何URL調用的代碼。
4.返回的JSON數據樣例
{"result":[{"table":[["iid",26,0,0,50,102,102,0,false,false,0,false,false],["name",26,1,0,50,102,102,0,false,false,0,false,false]],"iid":["1","2"],"name":["\u6D4B\u8BD5\u4E00","\u6D4B\u8BD5\u4E8C"]}]}
各開發語言解析JSON數據而後呈現。
後記:
delphi xe5新增長了RESTCLIENT組件,用它替代indy的http控件調用REST WEBSERVICE,不再用人工去解析返回的JSON格式去生成CLIENTDATASET數據了,設置幾個屬性便可,幾乎是零編碼。
unit Unit1;
interface
uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IPPeerClient, Data.DB, Datasnap.DBClient, REST.Response.Adapter, REST.Client, Data.Bind.Components, Data.Bind.ObjectScope, Vcl.StdCtrls, Vcl.Grids, Vcl.DBGrids, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, superobject;
type TForm1 = class(TForm) DBGrid1: TDBGrid; Button1: TButton; DataSource1: TDataSource; ClientDataSet1: TClientDataSet; IdHTTP1: TIdHTTP; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure rest_exec(cds: TClientDataSet; url: string); var jo: ISuperObject; ja, jb, jc: TSuperArray; i, h: Integer; FieldList: TStringList; arr: array of array of string; http: TIdHTTP; begin FieldList := TStringList.Create; http := TIdHTTP.Create(nil); try jo := so(http.Get(url)); ja := jo['result'].AsArray; // 獲取字段列表 jb := ja[0]['table'].AsArray; for i := 0 to jb.Length - 1 do begin jc := jb[i].AsArray; FieldList.add(jc[0].AsString) end; // 數據集建立字段 cds.close; cds.FieldDefs.Clear; for i := 0 to FieldList.Count - 1 do begin cds.FieldDefs.add(FieldList[i], Data.DB.ftString, 100, False); end; cds.CreateDataSet; // 數據集填充數據 SetLength(arr, ja[0][FieldList[0]].AsArray.Length, FieldList.Count); for i := 0 to FieldList.Count - 1 do begin // col jb := ja[0][FieldList[i]].AsArray; for h := 0 to jb.Length - 1 do begin // row arr[h, i] := jb[h].AsString; end; end; cds.DisableControls; try for i := 0 to jb.Length - 1 do begin // row cds.Append; for h := 0 to FieldList.Count - 1 do begin // col cds.Fields[h].Value := arr[i, h]; end; cds.Post; end; finally cds.EnableControls; end;
finally FieldList.Free; http.Free; end; end;
procedure TForm1.Button1Click(Sender: TObject); var url: string; begin url := 'http://localhost:18888/cxg/middle/TSysMethods/rest_GetData/select * from pos_master/0'; rest_exec(ClientDataSet1, url); end;
end.