Десериализация вложенного объекта json с использованием Delphi 2012
Я работаю над оболочкой для dropbox в Delphi 2012. Проблема, с которой я сталкиваюсь, заключается в десериализации ответов json. Когда я делаю запрос на список папок и файлов в моей учетной записи, я получаю ответ, который выглядит примерно так:
{
"hash": "some_hash",
"thumb_exists": false,
"bytes": 0,
"path": "/",
"is_dir": true,
"size": "0 bytes",
"root": "dropbox",
"contents":
[
{
"revision": 11,
"rev": "b074cbcbb",
"thumb_exists": false,
"bytes": 0,
"modified": "Mon, 23 Apr 2012 19:19:27 +0000",
"path": "/Apps",
"is_dir": true,
"icon": "folder",
"root": "dropbox",
"size": "0 bytes"
},
{
"revision": 142,
"rev": "8e074cbcbb",
"thumb_exists": false,
"bytes": 0,
"modified": "Wed, 09 May 2012 22:55:44 +0000",
"path": "/code",
"is_dir": true,
"icon": "folder",
"root": "dropbox",
"size": "0 bytes"
},
{
"revision": 7,
"rev": "7074cbcbb",
"thumb_exists": false,
"bytes": 246000,
"modified": "Mon, 23 Apr 2012 18:40:51 +0000",
"client_mtime": "Mon, 23 Apr 2012 18:40:52 +0000",
"path": "/Getting Started.pdf",
"is_dir": false,
"icon": "page_white_acrobat",
"root": "dropbox",
"mime_type": "application/pdf",
"size": "240.2 KB"
}
],
"icon": "folder"
}
Я хотел бы иметь возможность проанализировать это с помощью объекта TJSONUnMarshal, но оказывается, что TJSONUnMarshal ожидает, что json будет выглядеть следующим образом:
{
"type":"DropboxApiU.TFile",
"id":1,
"fields":
{
"hash": "some_hash",
"thumb_exists": false,
"bytes": 0,
"path": "/",
"is_dir": true,
"size": "0 bytes",
"root": "dropbox",
"contents":
[
{
"type":"DropboxApiU.TFile",
"id":1,
"fields":
{
"revision": 11,
"rev": "b074cbcbb",
"thumb_exists": false,
"bytes": 0,
"modified": "Mon, 23 Apr 2012 19:19:27 +0000",
"path": "/Apps",
"is_dir": true,
"icon": "folder",
"root": "dropbox",
"size": "0 bytes"
}
},
Я посмотрел на эту страницу и подумал, что это может быть то, что я ищу, но на самом деле это никогда не касается того, как использовать TTypeObjectReverter (который я думаю, это то, что мне нужно использовать), и я не могу найти пример онлайн.
Что было бы лучшим способом сделать это? Я надеюсь, что смогу просто написать TTypeObjectReverter или что-то подобное, но мне нужно будет посмотреть образец, чтобы я мог обернуть голову вокруг этого.
Вот скриншот различий между ними. Красный не отправляется в ответ от сервера Dropbox, но ожидается, что unmarshaler.
2 ответа
Вы можете использовать мой класс SvSerializer для этой задачи. Во-первых, вам нужно определить свой класс, который вы хотите сериализовать / десериализовать, например:
TDropbox = class
private
FHash: string;
Fthumb_exists: Boolean;
Fbytes: Integer;
Fpath: string;
Fis_dir: Boolean;
FSize: string;
Froot: string;
Fcontents: TArray<TContent>;
Ficon: string;
public
[SvSerialize]
property Hash: string read FHash write FHash;
[SvSerialize]
property thumb_exists: Boolean read Fthumb_exists write Fthumb_exists;
[SvSerialize]
property bytes: Integer read Fbytes write Fbytes;
[SvSerialize]
property path: string read Fpath write Fpath;
[SvSerialize]
property is_dir: Boolean read Fis_dir write Fis_dir;
[SvSerialize]
property size: string read FSize write FSize;
[SvSerialize]
property root: string read Froot write Froot;
[SvSerialize]
property contents: TArray<TContent> read Fcontents write Fcontents;
[SvSerialize]
property icon: string read Ficon write Ficon;
end;
TContent = record
private
frevision: Integer;
Frev: string;
Fthumb_exists: Boolean;
Fbytes: Integer;
fmodified: string;
fclient_mtime: string;
fpath: string;
fis_dir: Boolean;
ficon: string;
froot: string;
fmime_type: string;
fsize: string;
public
property revision: Integer read frevision write frevision;
property rev: string read Frev write Frev;
property thumb_exists: Boolean read Fthumb_exists write Fthumb_exists;
property bytes: Integer read Fbytes write Fbytes;
property modified: string read fmodified write fmodified;
property client_mtime: string read fclient_mtime write fclient_mtime;
property path: string read fpath write fpath;
property is_dir: Boolean read fis_dir write fis_dir;
property icon: string read ficon write ficon;
property root: string read froot write froot;
property mime_type: string read fmime_type write fmime_type;
property size: string read fsize write fsize;
end;
Затем добавьте экземпляр объекта TDropbox в сериализатор:
FSerializer := TSvSerializer.Create();
FDropboxFile := TDropbox.Create;
FSerializer.AddObject('', FDropboxFile);
И теперь вы можете сериализовать / десериализовать этот объект через SvSerializer:
FSerializer.DeSerialize(mmo1.Lines.Text{your json string, stream or filename}, TEncoding.UTF8{if it is string you must specify the encoding});
//After this line your FDropBoxFile's properties are filled from your json string
Может быть, вы могли бы попробовать вместо этого использовать JSON Wrapper от Progdigy?