Delphi オブジェクトのJSON直列化
この記事はDelphi Advent Calendar 2015 (#delphiadvent2015) の22日目の記事にあたります。
所定の要件を満たした Delphi バリューオブジェクトは JSON 文字列として直列化することができます。オブジェクトと JSON との間の双方向変換ができると、さまざまな場面で有益です。とはいえ、Delphi で利用できる型のうち、JSON と相互変換が可能+美しく変換できる型が どの型であるのかを知ることは重要です。
ここの例では、Delphiでバリューオブジェクトで作成したバリューオブジェクトをもちいて、JSON 文字列を取得します。ここで利用している型は、うつくしく JSON との相互変換が (デフォルトの挙動として) 実現が可能なものです。
オブジェクト→JSON
uses REST.JSON, uOrderVO, uOrderItemVO;
function TDataModule1.GetOrderAsJson: string; var Order: TOrderVO; OrderItem: TOrderItemVO; begin Order := TOrderVO.Create; // 注文情報 Order.OrderNo := 'P12345'; Order.TotalPrice := 1600; // 注文アイテム OrderItem := TOrderItemVO.Create; OrderItem.ItemNo := 'Item0001'; OrderItem.Price := 150; OrderItem.Amount := 3; Order.AddItem(OrderItem); // 注文アイテム OrderItem := TOrderItemVO.Create; OrderItem.ItemNo := 'Item0002'; OrderItem.Price := 230; OrderItem.Amount := 5; Order.AddItem(OrderItem); // 注文バリューオブジェクトを JSON 文字列に変換 Result := TJson.ObjectToJsonString(Order); end;
JSON→オブジェクト
その逆に、直列化された JSON文字列からオブジェクトへの逆直列化は以下のように記述します。こちらはとても簡単です。ジェネリクスの記述を忘れずに。
// JSON から注文バリューオブジェクトを復元
Result := TJson.JsonToObject<TOrderVO>(jsonText);
バイナリの扱い
バイナリを扱う場合 Delphi バリューオブジェクトでバイナリ利用 で示すようにバリューオブジェクトをつくると、適切かつ美しく JSON 直列化を実現することができます。例えば TImage の画像データを扱う場合には、ストリームを経由して TBytes に相互変換してから直列化するのです。
なお、この例では バリューオブジェクト側にヘルパーメソッドを追加していますが、これはお好み、あるいは規模が大きいシステムの場合には何らかの共通化を実施するのが妥当であろうと考えます。