Mostrando entradas con la etiqueta json. Mostrar todas las entradas
Mostrando entradas con la etiqueta json. Mostrar todas las entradas

viernes, 15 de mayo de 2015

Serialización sencilla JSON (II)

Vamos a ver de manera sencilla como crear la el objeto JSON personalizado de nuestra clase,
para eso veamos la clase creada:
unit Unit1;

interface

uses
  Data.DBXJSON;

type
  TMyclass = class(TObject)
  private
    FIntegerValue: Integer;
    FDoubleValue: Double;
    FStringValue: string;
  public
    class function FromJsonObject(const AJsonObject: TJSONObject): TMyClass;
    class function FromJsonString(const AJsonString: string): TMyClass;
    function ToJsonObject: TJSONObject;
    function ToJsonString: string;
  published
    property IntegerValue: Integer read FIntegerValue write FIntegerValue;
    property DoubleValue: Double read FDoubleValue write FDoubleValue;
    property StringValue: string read FStringValue write FStringValue;
  end;

implementation

uses
  System.SysUtils;

{ TMyclass }

class function TMyclass.FromJsonObject(
  const AJsonObject: TJSONObject): TMyClass;
begin
  Result := TMyclass.Create;
  if Assigned(AJsonObject) then
  begin
    Result.FIntegerValue := TJSONNumber(AJsonObject.Get('I').JsonValue).AsInt;
    Result.FDoubleValue := TJSONNumber(AJsonObject.Get('D').JsonValue).AsDouble;
    Result.FStringValue := TJSONString(AJsonObject.Get('S').JsonValue).Value;
  end;
end;

class function TMyclass.FromJsonString(const AJsonString: string): TMyClass;
var
  AJson: TJSONValue;
begin
  AJson := TJSONObject.ParseJSONValue(AJsonString);
  try
    Result := FromJsonObject(TJSONObject(AJson));
  finally
    if Assigned(AJson) then
      AJson.Free;
  end;
end;

function TMyclass.ToJsonObject: TJSONObject;
begin
  Result := TJSONObject.Create;
  Result.AddPair('I',TJSONNumber.Create(FIntegerValue));
  Result.AddPair('D',TJSONNumber.Create(FDoubleValue));
  Result.AddPair('S',TJSONString.Create(FStringValue));
end;

function TMyclass.ToJsonString: string;
begin
  with ToJsonObject do
  try
    Result := ToString;
  finally
    Free;
  end;
end;

end.

TMyClass es una ampliación de lo que vimos en el post anterior (Serialización sencilla en JSON), aquí el cotarro está en ToJsonObject y FormJsonObject, donde usamos el método AddPair de TJSONObject para ir añadiendo los campos que queremos serializar. que posteriormente recuperaremos con la función Get.

Como ejemplo:
function Test: string;
begin
  with TMyclass.Create do
    try
      IntegerValue := MaxInt;
      DoubleValue := 100728.897;
      StringValue := 'Hola Mundo';
      Result := ToJsonString;
    finally
      Free;
    end;
end;
Result = {"I":2147483647,"D":100728.897,"S":"Hola Mundo"}

Ahora vamos a ver como funcionan los arrays, para verlo podemos crear una lista de objetos, como
...
type
  TMyClassList = class(TObjectList<TMyclass>)
  public
    class function FromJsonObject(const AJsonObject: TJSONObject): TMyClassList;
    class function FromJsonString(const AJsonString: string): TMyClassList;
    function ToJsonObject: TJSONObject;
    function ToJsonString: string;
  end;
...
class function TMyClassList.FromJsonObject(const AJsonObject: TJSONObject): TMyClassList;
var
  AJsonArray: TJSONArray;
  i: Integer;
begin
  Result := TMyClassList.Create;
  if Assigned(AJsonObject) then
  begin
    AJsonArray := TJSONArray(AJsonObject);
    for i := 0 to AJsonArray.Size - 1 do
      Result.Add(TMyclass.FromJsonObject(TJSONObject(AJsonArray.Get(i))));
  end;
end;

class function TMyClassList.FromJsonString(const AJsonString: string): TMyClassList;
var
  AJson: TJSONValue;
begin
  AJson := TJSONObject.ParseJSONValue(AJsonString);
  try
    Result := FromJsonObject(TJSONObject(AJson));
  finally
    if Assigned(AJson) then
      AJson.Free;
  end;
end;

function TMyClassList.ToJsonObject: TJSONObject;
var
  AJsonArray: TJSONArray;
  i: Integer;
begin
  AJsonArray := TJSONArray.Create;
  for i := 0 to Count - 1 do
    AJsonArray.AddElement(Items[i].ToJsonObject);
  Result := TJSONObject(AJsonArray);
end;

function TMyClassList.ToJsonString: string;
begin
  with TJSONArray(ToJsonObject) do
    try
      Result := ToString;
    finally
      Free;
    end;
end;
...
He usado las mismas pautas que en TMyClass para ver de forma sencilla podemos generarlo. Usamos TJSONArray.AddElement para crear los elementos y Get para recuperarlos.

Como ejemplo
function TForm2.Test: string;
var
  a: TMyclass;
  b: TMyClassList;
begin
  b := TMyClassList.Create;
  try
    a := TMyclass.Create;
    with a do
    begin
      IntegerValue := MaxInt;
      DoubleValue := 100728.897;
      StringValue := 'Antonio';
    end;
    b.Add(a);
    a := TMyclass.Create;
    with a do
    begin
      IntegerValue := 0;
      DoubleValue := 827.09;
      StringValue := 'Pedro';
    end;
    b.Add(a);
    a := TMyclass.Create;
    with a do
    begin
      IntegerValue := -MaxInt;
      DoubleValue := -3.141596;
      StringValue := 'Jose';
    end;
    b.Add(a);
    Result := b.ToJsonString;
  finally
    b.Free;
  end;
end;
Result = [{"I":2147483647,"D":100728.897,"S":"Antonio"},{"I":0,"D":827.09,"S":"Pedro"},{"I":-2147483647,"D":-3.141596,"S":"Jose"}]

De una forma sencilla podemos crear nuestra propia serialización.


sábado, 9 de mayo de 2015

Serialización sencilla en JSON

El desarrollo de DataSnap Rest en Delphi (desde XE si no me equivoco)implica que disponemos de unas librerías que nos permiten la serialización de los objetos en JSON. Además se nos ofrecen varios tipos de clases y utilidades que nos permitirá tener estructuras complejas en JSON y poder serializar manualmente cualquier objeto (dentro de la capacidad de la Rtti).
 TJson = class(TObject)
  public
    class function ObjectToJsonObject(AObject: TObject; AOptions: TJsonOptions = []): TJSOnObject;
    class function ObjectToJsonString(AObject: TObject; AOptions: TJsonOptions = []): string;
    class function JsonToObject<T: class, constructor>(AJsonObject: TJSOnObject): T; overload;
    class function JsonToObject<T: class, constructor>(AJson: string): T; overload;
    class function Format(AJsonValue: TJsonValue): string;
  end;
Si no queremos complicarnos la vida, existen funciones que directamente nos hacen el trabajo, se encuentran en la unidad REST.Json, a través de su clase TJson:

Estas funciones nos permiten convertir cualquier objeto en un objeto o cadena JSON y viceversa, su uso es muy sencillo, sólo debemos indicar el objeto, clase y/o cadena a convertir.

Como ejemplo de su simplicidad:
...
type
  TMyClass = class(TObject)
  ...
  public
    function ToJsonString: string;
    class function CreateFromJsonString(const AJsonString: string): TMyClass;
  end;
...
function TMayClass.ToJsonString: string
begin
  Result := REST.Json.TJson.ObjectToJsonString(Self);
end;

class function TMyClass.CreateFromJsonString(const AJsonString: string): TMyClass;
begin
  Result := REST.Json.TJson.JsonToObject<TMyClass>(AJsonString);
end;
...

En muchas ocasiones, estas funciones nos serán de utilidad, en otras ya tendremos que adentrarnos más en el funcionamiento de los objetos json de Delphi y generar nosotros mismos la conversión .