Einzelnen Beitrag anzeigen

Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

Erste Schritte mit Rest.Json.pas: Wann braucht man einen eigenen TJsonInterceptor?

  Alt 2. Okt 2014, 11:13
Delphi-Version: 5
Da bin ich wieder. Es werden noch viele Fragen zu diesem Thema kommen da leider selbst in XE7 noch alles vollkommen undokumentiert ist.

Es tut mir leid um den vielen Code, ich habe extra das vorgestern erschienene "Delphi cookbook" geholt. Es bietet ein Beispiel zu genau meiner Frage, aber leider ebenfalls undokumentiert. Deshalb kann ich es fast nicht verstehen.


Nehmen wir an, ich habe folgende zwei Typen:
Delphi-Quellcode:
TInnerType = class(TInterfacedObject, IInterface)
   public var
      [JSonName('someValue')]
      someValue: Single;
   public
      constructor Create(); // Setzt someValue auf 42.99
end;

TOuterType = class
   protected var
      [JSonName('someSimpleField')]
      someSimpleField: Integer;
      [JSonName('someAdvancedField')]
      someAdvancedField: IInterface;
   public
      constructor Create(); // Setzt someSimpleField auf 42 und
      // someAdvancedField auf eine neue TInnerType-Instanz
end;
Wandele ich eine TOuterType-Instanz in JSON um, ist die Ausgabe
Code:
{"someSimpleField":42}
. Das Feld "someAdvancedField" fehlt völlig.

Im Beispiel von Daniele Tetis Buch serialisiert er eine Klasse TPhoto nach JSON. Diese Klasse enthält einen TStream. Damit dieser TStream serialisiert wird hängt er ein Attribut [JSONReflect(ctString, rtString, TStreamInterceptor)] an das Feld. Den TStreamInterceptor hat er dann selber geschrieben.


Was ich dann tat: Ich fühlte mich schlau und fügte meinem Feld "someAdvancedField" ebenfalls folgendes Attribut hinzu:
Delphi-Quellcode:
TOuterType = class
   protected var
      [JSonName('someSimpleField')]
      someSimpleField: Integer;
      [JSonName('someAdvancedField')] [JSonReflect(ctObjects, rtObject, TJSONInterceptor )]
      someAdvancedField: IInterface;
   public
      constructor Create();
end;
Als Ergebnis gibt es:
Code:
{"someSimpleField":42,"someAdvancedField":[]}
Ich hatte das Gefühl schon fast da zu sein. Aber ein Blick auf die Implementation von Rest.JSonReflect.TJSONInterceptor bringt nur eine Klasse mit leeren Methoden zu Tage. Muss ich jetzt wirklich für jeden Firlefanz einen eigenen Interceptor schreiben? Oder gehe ich hier grade einen völlig falschen Weg?

Ich versuche meine Nerverei so klein wie möglich zu halten, aber mir fehlt irgendwie das Grundverständnis wie die Embarcadero-Serialisierung vonstatten gehen soll: Die letzten Embarcadero-Videos zu JSON behandeln nur trivialste Dinge wie das Anzeigen des JSON-Strings in Memos. Dokumentation scheint überhaupt keine vorhanden. Ich weiß noch nicht einmal, was der Unterschied zwischen dem Kram aus Rest.Json.pas und Data.DBXJSONReflect.pas ist. Das Posten des Beispiels aus dem Buch habe ich bewusst vermieden, Copyright und so.
  Mit Zitat antworten Zitat