Sign in Join
Wiki copytemporary

Streaming JSON/ru: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11> **Note:** Эта статья является перевод статьи с английского [[Streaming JSON]] от 2014-10-02, которая была переведена с помощью Google Translate с немецкого (оригинал). Понятно, что результат перевода может быть ужасным, вполне может требоваться ручная корректировка. **Убедительная просьба не использовать автоматический перевод без окончательной обработки**
22
33[[JSON]](JavaScript Object Notation) является текстовым, стандартизированным форматом данных. Как следует из названия, JSON документы являются правильным кодом JavaScript, где они могут быть непосредственно преобразованы в объекты JavaScript. Но сам по себе JSON может быть использован независимо от используемого языка программирования для обмена данными.
44
55В этом руководстве объясняется, как загрузить данные в формате JSON в программе Free Pascal для обработки. Оно также объясняет, как преобразовать данные FPC в формате JSON (например, чтобы отправить их на веб-сервер).
66
77## Общие положения и условия
88
99Загрузка и хранение (маршалинг) FPC данных объекта осуществляется с помощью юнита "fpjsonrtti". Кроме того, может пригодиться класс Class в этом юните (см ниже).
1010
1111В связи с этим оператор USES должен содержать, по крайней мере, эти два юнита:
1212
1313``` pascal
1414USES Classes, fpjsonrtti;
1515```
1616
1717В настоящее время (май 2014 г.) есть некоторые отличия от потоковой системы Free Pascal с ??_предположительно_ JavaScript ??:
1818
1919- Данные в формате JSON чувствительны к регистру. Таким образом, свойства объектов Free Pascal, как свойства JSON должны быть написаны с правильным регистром.
2020- Нет свойств, которые могут быть определены как DefineProperties. Нельзя сохранить ссылки на методы (обработчики событий).2
2121- [[TCollection]] и [[TStrings]] может быть использован в качестве замены массивов.
2222
2323Демо-версия программы предоставляется с исходным кодом Free Pascal Compiler (в папке /packages/fcl-json/examples).
2424
2525В качестве примера, мы приведём пример со следующими данными JSON:
2626
2727``` JavaScript
2828{
2929 "id" : 123, // Integer
3030 "obj" : { "name": "Привет, мир!" }, // Object
3131 "coll" : [ { "name": "Объект 1" }, { "name": "Объект 2" } ], // два объекта TCollection
3232 "strings": [ "привет 1", "привет 2" ] // список строк
3333}
3434```
3535
3636Это может быть выполнено в Free Pascal с использованием констант следующим образом:
3737
3838``` pascal
3939const JSON_TESTDATA =
4040'{'+LineEnding+
4141' "id": 123,'+LineEnding+
4242' "obj": { "name": "Привет, Мир!" },'+LineEnding+
4343' "coll": [ { "name": "Объект 1" }, { "name": "Объект 2" } ],'+LineEnding+
4444' "strings": [ "привет 1", "привет 2" ]'+LineEnding+
4545'}';
4646```
4747
4848## Структура данных
4949
50-В качестве базового класса для обслуживания данных существует класс [[TPersistent]] из юнита Classes, так как для них и всех подклассов должен быть создан [[Runtime Type Information (RTTI)|Laufzeit-Typinformationen]] (<abbr title="Runtime Type Information">RTTI</abbr>). Это совершенно необходимо для маршаллинга. Поскольку fpjsonrtti не интегрирован в систему маршаллинга, любого другого класса, должна быть указана опция компилятора **{\$M+}**, для использования.
50+В качестве базового класса для обслуживания данных существует класс [[TPersistent]] из юнита Classes, так как для них и всех подклассов должен быть создан [[Runtime Type Information (RTTI)|Laufzeit-Typinformationen]] (RTTI). Это совершенно необходимо для маршаллинга. Поскольку fpjsonrtti не интегрирован в систему маршаллинга, любого другого класса, должна быть указана опция компилятора **{\$M+}**, для использования.
5151
5252Все объекты должны быть доступны как [[Property|property]] для чтения в разделе класса [[Published|published]]. В общем случае (переменная) должна быть доступна для чтения и записи непосредственно в поле данных. Если вы хотите, конечно, могут быть использованы методы getter и setter.
5353
5454Для структуры JSON результаты определении класса представлены ниже.
5555
5656``` Pascal
5757TYPE
5858 TNameObject = CLASS(TCollectionItem) // класс для свойства 'obj' и TCollection
5959 PRIVATE
6060 fName: String;
6161 PUBLISHED
6262 property name: String read fName write fName;
6363 END;
6464
6565 TBaseObject = CLASS(TPersistent) // класс для структуры JSON
6666 PRIVATE
6767 fid: Integer;
6868 fObj: TNameObject;
6969 fColl: TCollection;
7070 fStrings: TStrings;
7171 PUBLIC
7272 CONSTRUCTOR Create;
7373 DESTRUCTOR Destroy; override;
7474 PUBLISHED// все свойства должны быть published
7575 PROPERTY id: Integer read fid write fid;
7676 PROPERTY obj: TNameObject read fObj write fObj;
7777 PROPERTY coll: TCollection read fColl;
7878 PROPERTY strings: TStrings read fStrings;
7979 END;
8080```
8181
8282Класс `TNameObject` является потомком [[TCollectionItem]]. Таким образом, они могут оба для свойства *obj* использовать коллекции. Если это не желательно, здесь должны быть определены два различных класса.
8383
8484В конструкторе класса TBaseObject класс TCollection и список строк должен быть создан конструктором и уничтожен в деструкторе.
8585
8686``` Pascal
8787CONSTRUCTOR TBaseObject.Create;
8888BEGIN
8989 // конструктор коллекции и StringList
9090 fColl := TCollection.Create(TNameObject);
9191 fStrings := TStringList.Create;
9292 fObj := TNameObject.Create(nil);
9393END;
9494
9595DESTRUCTOR TBaseObject.Destroy;
9696BEGIN
9797 // деструктор коллекции и StringList
9898 fColl.Free;
9999 fStrings.Free;
100100 fObj.Free;
101101 INHERITED Destroy;
102102END;
103103```
104104
105105Если вы не хотите больше функций для данных классов, их определение закончено.
106106
107107## Загрузка JSON
108108
109109С помощью метода `Procedure JSONToObject(Const JSON : TJSONStringType; AObject : TObject);` в классе [[TJSONDeStreamer]] вы можете присвоить данные в формате JSON непосредственно *существующему* объекту; перед тем, как вызвать этот метод, вы должны создать TJSONDeStreamer и целевой объект.
110110
111111Следующий метод загружает данные из структуры JSON `JSON_TESTDATA` в объект "о" и затем выводит текущие значения свойств в консоли.
112112
113113``` pascal
114114PROCEDURE DeStreamTest;
115115VAR
116116 DeStreamer: TJSONDeStreamer;
117117 o: TBaseObject;
118118 no: TNameObject;
119119 s: String;
120120BEGIN
121121 WriteLn('тест DeStream');
122122 WriteLn('======================================');
123123
124124 // объект DeStreamer и целевой объект
125125 DeStreamer := TJSONDeStreamer.Create(nil);
126126 o := TBaseObject.Create;
127127 TRY
128128 // загрузка данных JSON в объект o
129129 DeStreamer.JSONToObject(JSON_TESTDATA, o);
130130 // ID
131131 WriteLn(o.id);
132132 // имя объекта
133133 WriteLn(o.obj.name);
134134 // напечатать имена всех объектов
135135 for TCollectionItem(no) in o.coll do
136136 Writeln(no.name);
137137 // вывести все строки
138138 for s in o.strings do
139139 WriteLn(s);
140140
141141 // очистка
142142 FINALLY
143143 o.Destroy;
144144 DeStreamer.Destroy;
145145 END;
146146END;
147147```
148148
149149## Сохранение JSON
150150
151151Для преобразования объекта в текст JSON, используется класс [[TJSONStreamer]]. Здесь используется метод `FUNCTION ObjectToJSONString(AObject : TObject) : TJSONStringType;`.
152152
153153В следующей процедуре, объект создается, заполняется данными теста, а затем преобразуются в формат JSON. Порядок, в котором сохраняются свойства не могут зависеть от программиста.
154154
155155И, наконец, текст JSON выводится на консоль.
156156
157157``` Pascal
158158PROCEDURE StreamTest;
159159VAR
160160 Streamer: TJSONStreamer;
161161 o: TBaseObject;
162162 JSONString: String;
163163BEGIN
164164 WriteLn('Stream test');
165165 WriteLn('======================================');
166166
167167 Streamer := TJSONStreamer.Create(nil);
168168 o := TBaseObject.Create;
169169 TRY
170170 // установка данных
171171 o.id := 123;
172172 o.obj.name := 'Привет, мир!';
173173 TNameObject(o.coll.Add).name := 'Объект 1';
174174 TNameObject(o.coll.Add).name := 'Объект 2';
175175 o.strings.Add('Привет 1');
176176 o.strings.Add('Привет 2');
177177
178178 Streamer.Options := Streamer.Options + [jsoTStringsAsArray]; // сохранение строки в JSON
179179 // конвертация вывод и JSON
180180 JSONString := Streamer.ObjectToJSONString(o);
181181 WriteLn(JSONString);
182182
183183 // очистка
184184 FINALLY
185185 o.Destroy;
186186 Streamer.Destroy;
187187 END;
188188END;
189189```
190190
191191## Вывод
192192
193193С помощью представленного знания, простые и сложные структуры данных JSON могут быть загружены в ваши программы на Free Pascal. Если необходима какая-либо пред- или постобработка данных JSON, текстовые данные могут быть изначально загружены в структуру данных в формате JSON (классом [[TJSONParser]] из юнита [[jsonparser]]), а затем можно обрабатывать с помощью юнита [[fpJSON]].
194194
195195Опции свойства TJSONStreamer могут быть использованы для управления представлением ваших собственных структур данных в формате JSON.
196196
197197## Смотрите также
198198
199199- [[JSON/ru|JSON]]
200200- [[fcl-json/ru|fcl-json]]
201201- [[Streaming components]]
202202
203203## Примечания & Ссылки
204204
205-1. <div id="ref1">
206-
207- <http://lists.freepascal.org/fpc-pascal/2013-January/036254.html>
208-
209- </div>
205+1. <http://lists.freepascal.org/fpc-pascal/2013-January/036254.html>
210206
2112072. \<div id="ref2\>http://lists.lazarus.freepascal.org/pipermail/lazarus/2011-January/058878.html
212- </div>
213208
214209---
215210*From the Free Pascal wiki, page "Streaming JSON/ru", as it stood on 2022-08-06 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history