Примеры использования JSON в Synopse mORMot Framework

Февраль 27, 2013 — Шарахов А.П.

Поддержка JSON довольно сильно интегрирована в mORMot. Возможности сериализации весьма широки, хотя не все из них находятся на поверхности.

Замечательно, что сериализация объектов в mORMot построена на основе RTTI, даже для старых версий Delphi. Сериализуемые свойства объектов должны быть объявлены как published.

Сериализация простых свойств (число, дата, строка, булевский тип) выполняется автоматически и каких-либо cложностей не представляет.

Сериализация структурных свойств (запись, массив записей и массив значений) также выполняется автоматически, но по умолчанию происходит их преобразование в Base64-строку. Если требуется получить читаемое представление, то надо написать несложные функции обратного вызова Reader/Writer или использовать массивы предопределенных типов.

В прилагаемом исходнике я специально не использовал предопределенные типы массивов для того, чтобы продемонстрировать возможность переключения представления данных.

Также обратите внимание, что перед десериализацией JSON-строка предварительно копируется в промежуточный буфер. Это необходимо, т.к. данные в буфере изменяются при десериализации.

      SetString(s,pchar(pointer(JsonString)),Length(JsonString));
      JsonToObject(List, pointer(s), isValid);

Если JSON-строка после десериализации в программе не используется, то этот код можно сократить:

      JsonToObject(List, pointer(JsonString), isValid);

Немного покопавшись во внутренностях mORMot, можно обнаружить даже способ сериализации обычных записей или массивов записей. Как и при работе с объектами, в этом случае удается получить представление полей записи и в виде упорядоченного массива неименованных значений, и в виде AV-пар.

Добавление

Если ваш SynCommons.pas датирован 28.02.2013 или позднее, то вы можете немного упростить сериализацию массивов записей, например:

procedure TForm1.bRecordArrayToJsonClick(Sender: TObject);
var
  ra: TDynRecordArray;
  wr: TTextWriter;
  i: integer;
begin;
  SetLength(ra,5);
  for i:=0 to Length(ra)-1 do FillRecord(ra[i], i);
 
  wr:=TTextWriter.CreateOwnedStream;
  try
    wr.AddDynArrayJson(TypeInfo(TDynRecordArray),ra);
    JsonString:=wr.Text;
  finally
    wr.Free;
    end;
 
  Memo1.Text:=UTF8ToString(JsonString);
  end;
 
procedure TForm1.bRecordArrayFromJsonClick(Sender: TObject);
var
  ra: TDynRecordArray;
  isValid: boolean;
  s: RawUTF8;
  i: integer;
begin;
  Memo2.Lines.Clear;
 
  if JsonString<>'' then begin;
    SetString(s,pchar(pointer(JsonString)),Length(JsonString));
    isValid:=DynArrayLoadJSON(ra,pointer(s),TypeInfo(TDynRecordArray))<>nil;
    if not isValid then Memo2.Lines.Text:='invalid JSON string'
                   else for i:=0 to Length(ra)-1 do ShowRecord(ra[i], Memo2);
    end;
  end;

на главную

Прикрепленный файлРазмер
JsonProj.zip6.04 кб

Comments (5)

обратите внимание на то, что

обратите внимание на то, что модуль SynCommons.pas не является кросс-платформенным. Возможно, кому-то поможет избежать ошибок.

Буффер

А нельзя сделать просто?

S := JsonString; UniqueString( s );

Буффер

Конечно, можно.

Delphi xe3

Dont work in delphi xe 3 update 2 , i have to add
SynCommons. in ttextwrite but record to json product this

"￰bQEAAJP+////////AAAAAABAQkAXU+ovQ2DkQApkAGEAeQAvADMA"

roberio.praciano@gmail.com

Brazil

Record format

Do you set radio button named "Record (array) format"?