jjw

写给自己的博客。 记录学习的点滴以备查。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

delphi JSON序列化(四)

Posted on 2024-01-10 16:41  jjw  阅读(276)  评论(0编辑  收藏  举报

涉及的重要类 REST.Json,REST.JsonReflect,REST.Json.Interceptors, REST.Json.Types单元中。

一、TJson类

最简单的一个类,提供了JSON -> OBJECT和OBJECT -> JSON几个方法,方法有TJsonOptions参数,如:

    class function ObjectToJsonObject(AObject: TObject; AOptions: TJsonOptions = CDefaultOptions): TJSONObject;

type
  TJsonOption = (joIgnoreEmptyStrings, joIgnoreEmptyArrays,
    joDateIsUTC, joDateFormatUnix, joDateFormatISO8601, joDateFormatMongo, joDateFormatParse,
    joBytesFormatArray, joBytesFormatBase64,
    joIndentCaseCamel, joIndentCaseLower, joIndentCaseUpper, joIndentCasePreserve,
    joSerialFields, joSerialPublicProps, joSerialPublishedProps, joSerialAllPubProps);
  TJsonOptions = set of TJsonOption;

TJsonOptions主要是控制一些转换细节,如日期类型的格式,Base64, 驼峰,属性的可见性等。

二、TConverter<TSerial> 类

这是一个抽象类,提供了序列化过程中的相关方法

三、  TJSONConverter = class(TConverter<TJSONValue>)

是TConverter<TSerial> 类的子类,实现了父类的抽象方法,同时也是默认的转换器。

四、TJSONMarshal和TJSONUnMarshal

这个类是正、反序列化的两个具体类。TJson内部就是使用这两个类完成工作的。

五、一些TCustomAttribute的子类

这些子类是“贴标签”用的,  如JSONMarshalledAttribute和JsonNameAttribute

  TPerson = class
  private
    fname: string;
    fage: Integer;
  public
    [JsonName('_new_name_')]
    property name: string read fname write fname;
    [JSONMarshalled(false)]
    property age: Integer read fage write fage;
  end;
//json结果 : {"_new_name_":"aaa"}

六、TJSONConverters类

这个类有几个静态方法,可以添加转换事件类。

七、TConverterEvent和TReverterEvent

这两个类是成对的,主要是定义了拦截事件。

八、TJSONInterceptor类

可以自定义不同的TJSONInterceptor子类,然后供JsonReflectAttribute属性标签用。

九、简单的示例

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Rest.JSON.Types, Rest.JsonReflect;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TTestInterceptor = class(TJSONInterceptor)
  public
    function StringConverter(Data: TObject; Field: string): string; override;  // 注意事项 2: 这个方法实现要追加的字符串。
    function TypeObjectConverter(Data: TObject): TObject; override;     //注意事项一:转换对象的这个方法一定要实现,
  end;

  [JSONSerialize(jmPublicProps)]  //
  [JsonReflect(ctTypeObject, rtTypeObject, TTestInterceptor)] //注意事项一:偷换了转换的对象,
  TPerson = class
  private
    fname: string;
    fage: Integer;
  public
    constructor Create(_name: string; _age: Integer);
    property name: string read fname write fname;
    property age: Integer read fage write fage;
  end;

  [JSONSerialize(jmPublicProps)]
  TPerson2 = class
  private
    fname: string;
    fage: Integer;
  public
    constructor Create;
    [JsonReflect(ctString, rtString, TTestInterceptor)]    //注意事项 2 :字符串属性内容转换。
    [JsonName('new_name_')]
    property name: string read fname write fname;
    [JSONMarshalled(false)]
    property age: Integer read fage write fage;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  REST.Json, System.Generics.Collections;

{ TPerson }

constructor TPerson.Create(_name: string; _age: Integer);
begin
  inherited Create;
  fname := _name;
  fage := _age;
end;

{ TPerson2 }

constructor TPerson2.Create;
begin
  inherited Create;
  fname := 'person222222';
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  var p := TPerson.Create('aaa', 1);
  var jsonValue := TJson.ObjectToJsonObject(p, [joIndentCaseUpper]);  // 注意:自定义转换后,name不会转为大写。
  Memo1.Text := jsonValue.toString;
  p.Free;
end;

{ TTestInterceptor }

function TTestInterceptor.StringConverter(Data: TObject; Field: string): string;
begin
  Result := RTTIProvider.GetMember(Data, Field).GetValue(Data).AsString + '__新加的内容';
end;

function TTestInterceptor.TypeObjectConverter(Data: TObject): TObject;
begin
  //这里偷换为 person2.
  Result := TPerson2.Create;
end;

end.
View Code

结果:{"new_name_":"person222222__新加的内容"}