Networking, JSON & XML
For object serialization, FPC's fpjsonrtti (TJSONStreamer/TJSONDeStreamer) converts published properties to and from JSON.
40.1 Networking libraries
fphttpclient / fphttpserver (FCL) built-in HTTP client/server; HTTPS via opensslsockets (FPC 3.2+) fcl-net (ssockets) TCP/UDP sockets Synapse (Ararat) lightweight blocking sockets: HTTP, SMTP, FTP, SNMP, serial both (bundled with Delphi, OPM for Lazarus) large component suite: TIdHTTP, TIdTCPServer, TIdSMTP,...
System.Net.HttpClient (THTTPClient, TNetHTTPClient) uses the OS HTTP stack (no OpenSSL needed)
REST client library (TRESTClient, TRESTRequest) REST + JSON binding
fpWeb, Brook, Horse, mORMot 2, DMVCFramework, RAD Server web/REST server frameworks
40.2 HTTP GET + JSON parsing (Free Pascal)
program HttpJson;
{$mode objfpc}{$H+}
uses
SysUtils, fphttpclient, opensslsockets, fpjson, jsonparser;
var
Client: TFPHTTPClient;
Body: string;
Data: TJSONData;
Obj: TJSONObject;
begin
Client := TFPHTTPClient.Create(nil);
try
Client.AddHeader('User-Agent', 'pascal-course');
Client.AllowRedirect := True;
Body := Client.Get('https://httpbin.org/get?lang=pascal');
Writeln('Status: ', Client.ResponseStatusCode);
finally
Client.Free;
end;
Data := GetJSON(Body);
try
Obj := Data as TJSONObject;
Writeln('URL: ', Obj.Get('url', ''));
Writeln('lang: ', Obj.Objects['args'].Get('lang', ''));
finally
Data.Free;
end;
end.40.3 Building JSON (fpjson)
For object serialization, FPC's fpjsonrtti (TJSONStreamer/TJSONDeStreamer) converts published properties to and from JSON.
uses fpjson;
var
Obj: TJSONObject;
begin
Obj := TJSONObject.Create(['name', 'Ada', 'age', 36, 'active', True]);
try
Obj.Add('languages', TJSONArray.Create(['Pascal', 'Delphi']));
Obj.Add('address', TJSONObject.Create(['city', 'London']));
Writeln(Obj.AsJSON); // compact
Writeln(Obj.FormatJSON); // pretty-printed
Writeln(Obj.Integers['age'], ' ', Obj.Strings['name']);
finally
Obj.Free; // frees all children
end;
end.40.4 HTTP and JSON in Delphi
REST.Json.TJson.ObjectToJsonString(Obj) and TJson.JsonToObject<T>(S) serialize whole objects (fields), and System.JSON.Serializers offers attribute-driven serialization.
uses System.SysUtils, System.JSON, System.Net.HttpClient;
procedure Demo;
var
Client: THTTPClient;
Resp: IHTTPResponse;
Obj: TJSONObject;
V: TJSONValue;
begin
Client := THTTPClient.Create;
try
Resp := Client.Get('https://httpbin.org/get?lang=pascal');
Writeln(Resp.StatusCode);
V := TJSONObject.ParseJSONValue(Resp.ContentAsString);
try
Writeln(V.GetValue<string>('args.lang')); // path syntax
finally
V.Free;
end;
finally
Client.Free;
end;
Obj := TJSONObject.Create;
try
Obj.AddPair('name', 'Ada');
Obj.AddPair('age', TJSONNumber.Create(36));
Obj.AddPair('languages', TJSONArray.Create.Add('Pascal').Add('Delphi'));
Writeln(Obj.ToJSON);
finally
Obj.Free;
end;
end;40.5 Other clients
// Synapse (both compilers)
uses httpsend, Classes;
var SL: TStringList;
begin
SL := TStringList.Create;
try
if HttpGetText('http://example.com/', SL) then Writeln(SL.Text);
finally
SL.Free;
end;
end.
// Indy (both compilers); HTTPS also needs TIdSSLIOHandlerSocketOpenSSL and OpenSSL DLLs
uses IdHTTP;
var HTTP: TIdHTTP;
begin
HTTP := TIdHTTP.Create(nil);
try
Writeln(HTTP.Get('http://example.com/'));
finally
HTTP.Free;
end;
end.40.6 XML
Free Pascal (units DOM, XMLRead, XMLWrite; Lazarus also has Laz2_DOM):
Delphi (Xml.XMLDoc, Xml.XMLIntf; console apps on Windows must call CoInitialize for the MSXML vendor):
Other options: OmniXML, NativeXml, FPC's SAX reader, and XPath (XPath unit in FPC, IDOMNodeSelect in Delphi).
uses DOM, XMLRead;
var
Doc: TXMLDocument;
Node: TDOMNode;
begin
ReadXMLFile(Doc, 'books.xml');
try
Node := Doc.DocumentElement.FirstChild;
while Assigned(Node) do
begin
if Node.NodeName = 'book' then
Writeln(TDOMElement(Node).GetAttribute('title'));
Node := Node.NextSibling;
end;
finally
Doc.Free;
end;
end.uses Xml.XMLIntf, Xml.XMLDoc;
var
Doc: IXMLDocument;
I: Integer;
begin
Doc := LoadXMLDocument('books.xml');
for I := 0 to Doc.DocumentElement.ChildNodes.Count - 1 do
Writeln(string(Doc.DocumentElement.ChildNodes[I].Attributes['title']));
end.