![]() |
RestServer Antwort Json ohne "[" Klammern
Ich muss euch nochmal stören.
Ich habe eine Serverantwort in Json von einem Rest server
Code:
Serverseite zum Üben
{"result":["Test<\u00F6\u00E4\u00FC\u00F6\u00E4\u00FC>7"]}
1["Test<öäüöäü>7"]
Delphi-Quellcode:
Nun möchte ich die "reine" Antwort. Bisher habe ich das mit RegEx erschlagen und möchte es nun aber gerne über den Json way probieren.
function TServerMethods1.updateEchoAttribute1(Key, Obj: string): String;
begin Result:= Key + '<öäüöäü>' + Obj; end;
Delphi-Quellcode:
var
LJSONObject: TJSONObject; RestResponse: string; begin RestResponse:= '{"result":["Test<\u00F6\u00E4\u00FC\u00F6\u00E4\u00FC>7"]}'; LJSONObject := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(RestResponse), 0) as TJSONObject; mmo1.Lines.Add(LJSONObject.Values['result'].ToString); end; Die schlichte Frage ist wie bekomme ich die -->[" und "]<-- Klammern/Gänsefüßchen entfernt. Ich hoffe ihr könnt helfen. lieben Gruß SM;) |
AW: RestServer Antwort Json ohne "[" Klammern
Kann es sein, dass es dazu vor Kurzem schonmal einen Thread gab? :?
ToString wird das JSON-"Objekt" als Text zurück geben. Es gibt aber bestimmt ein Value oder AsString, das den Wert liefert. :stupid: |
AW: RestServer Antwort Json ohne "[" Klammern
Genau das ist ja mein problemchen
Delphi-Quellcode:
liefert MIT besagten Zeichen
mmo1.Lines.Add(LJSONObject.Values['result'].ToString);
Code:
["Test<öäüöäü>7"]
|
AW: RestServer Antwort Json ohne "[" Klammern
Delphi-Quellcode:
ist von der Definition her dafür da, die Instanz als String darzustellen.
ToString
Das willst du aber nicht, du willst den Wert.
Delphi-Quellcode:
liefert ein
TJSONObject.Values[...]
Delphi-Quellcode:
und wenn das vom Type ein
TJSONValue
Delphi-Quellcode:
ist, dann bekommt man bei
TJSONString
Delphi-Quellcode:
auch den gesuchten String-Wert.
TJSONString.Value
EDIT Stop, Kommando zurück, du hast dort ein
Delphi-Quellcode:
und der erste Wert ist dann ein
TJSONArray
Delphi-Quellcode:
;)
TJSONString
|
AW: RestServer Antwort Json ohne "[" Klammern
Magst mich gerade noch Aufklären wie ich mit einem solchen Array umzugehen habe?
Da bin ich noch Jungfräulich Gruß SM;) |
AW: RestServer Antwort Json ohne "[" Klammern
Und jetzt nochmal meine Antwort lesen. :roll:
Zitat:
|
AW: RestServer Antwort Json ohne "[" Klammern
Und wenn du von der gleichen Faulheit befallen bist wie ich, dann sparst du dir diesen gesamten Fuddelkram mit
Delphi-Quellcode:
und verarbeitest das ganz gemütlich mit
unit Unit2;
interface uses REST.Json.Types; // <- da sind die Json-Attribute definiert type TResponseJSON = class private [ JsonName( 'result' ) ] FResultArray: TArray<string>; public property ResultArray: TArray<string> read FResultArray; end; implementation end.
Delphi-Quellcode:
Weil einfach einfach einfach ist :stupid:
program foo;
uses System.SysUtils, REST.Json, // <- da ist TJson definiert Unit2 in 'Unit2.pas'; procedure Test; var lResponse: TResponseJSON; begin lResponse := TJson.JsonToObject<TResponseJSON>( '{"result":["Test<\u00F6\u00E4\u00FC\u00F6\u00E4\u00FC>7"]}' ); try WriteLn( lResponse.ResultArray[ 0 ] ); finally lResponse.Free; end; end; begin try Test; except on E: Exception do WriteLn( E.ClassName, ': ', E.Message ); end; ReadLn; end. |
AW: RestServer Antwort Json ohne "[" Klammern
TsTsTs ... muss man immer alles dreimal sagen
![]() :stupid: |
AW: RestServer Antwort Json ohne "[" Klammern
Nur zum Test.
Delphi-Quellcode:
?
S := (LJSONObject.Values['result'] as TJSONArray).Items[0].Value;
|
AW: RestServer Antwort Json ohne "[" Klammern
@himitsu
Doch gelesen habe ich es aber meine Versuche mit
Delphi-Quellcode:
scheitern. Ich bekomme '' als Antwort.
mmo1.Lines.Add('2' + LJSONObject.Values['result'].Value);
Wenn ich probiere dort gerade alles durch edit: gerade den Post gesehen ... probier ich gleich SirRufo :) das seh ich mir gleich mal an ^^ :))))) Gruß SM;) |
AW: RestServer Antwort Json ohne "[" Klammern
himitsu du bist echt ein Gott/Göttin!!!
Delphi-Quellcode:
funktioniert SUPER!!!!!!!!
S := (LJSONObject.Values['result'] as TJSONArray).Items[0].Value; ?
Danke dir!!!! Gruß SM;) PS: Troz allem werde ich SirRufos Code auch testen, allein um des lernens Willen !!! |
AW: RestServer Antwort Json ohne "[" Klammern
Aber nimm's nicht so schwer.
Ich fand die geklaute Implementation vom Embarcadero schon vom ersten Tag an Schrott, also was das Manuelle betrifft. Der Wrapper von/zu den Datenobjekten ist halbweg bauchbar. Geht allerdins nur, wenn man zur Designtime die Struktur kennt und passende Records/Datenobjekte schreibt. (dynamisch, zur Laufzeit was entscheiden, ist da dann nichts) |
AW: RestServer Antwort Json ohne "[" Klammern
Da ich mit dem RestServer erst beginne und ihn nur für mich privat brauchen werde, ist das zum üben vollkommen ausreichend.
Ich danke dir nochmal!! Gruß SM;) |
AW: RestServer Antwort Json ohne "[" Klammern
@himitsu
Wenn du von der API ständig überrascht wirst, was die so an Strukturen heraushaut, dann solltest du die API nochmal prüfen. Und egal was die zurückliefert, die Struktur muss irgendwie bekannt sein, denn wie will man den Inhalt verarbeiten, wenn man nicht weiß, was der Inhalt bedeutet. |
AW: RestServer Antwort Json ohne "[" Klammern
Ja, die Struktur muß bekannt sein, aber ich meine eher so, daß man bei den Klassen nicht zur Laufzeit eine andere Struktur nehmen kann, ohne schon vorher mehrere Klassen geschrieben zu haben.
|
AW: RestServer Antwort Json ohne "[" Klammern
Zitat:
Ich kann die Nachricht per Hand auseinandernehmen (dazu muss mir aber die Struktur zur DesignTime bekannt sein) oder die Nachricht in eine Klasse schreiben lassen (die ich nur schreiben kann, wenn mir die Struktur zur DesignTime bekannt ist). Der große Unterschied ist, dass ich bei der Verwendung von Klassen mit einer Zeile Code die Nachricht in einer Struktur habe, die ich in der Anwendung sehr einfach verarbeiten kann. Ohne schreibe ich jede Menge Code (mit potentiellen Fehlern) und schleppe eventuell sogar das JSON-Zeug kreuz und quer durch meine Anwendung. Und wenn sich an der Nachricht etwas ändert, dann kann man an n(+?) Stellen im Code suchen, wo denn das jetzt alles geändert werden muss. Bei der Verwendung von Klassen, kann ich diese Änderungen entweder verstecken oder finde sehr schnell die Stellen, wo mit so einer Instanz gearbeitet wird. |
AW: RestServer Antwort Json ohne "[" Klammern
Es kommt immer drauf an, wer die API geschrieben hat. Kam der Autor aus einer typsicheren Sprache, dann hält sich auch die API an ein definiertes Schema. Kommt der Autor aus einer der dynamischen Sprachen (oder kommen die Daten aus einer NoSQL-DB) dann kann sich die Struktur schon mal ändern.
Bei Shopware z.B. unterscheidet sich die Definition einer Ressource zwischen lesenden und schreibenden Zugriffen. Da hat dann z.B. ein Feld einen anderen Typ. Sowas ist furchtbar nervig, weil man für jede Variante dann eine Klasse haben muss, in die man serialisieren kann. |
AW: RestServer Antwort Json ohne "[" Klammern
Nunja, grundsätzlich ist das ja kein Problem (ja ein bisserl Tipparbeit mit den Klassen) wenn man es sich schon mal vorab gemütlich macht.
Delphi-Quellcode:
Dann geht das nachher alles wie von selber
unit Unit1;
interface uses System.Generics.Collections, System.SysUtils, REST.Json.Types; type { internal data object } TFooData = class private FNumber: Integer; public property Number: Integer read FNumber write FNumber; end; type { api objects } TFooWriteJson = class private [ JsonName( 'number_write' ) ] FNumber: string; public property Number: string read FNumber write FNumber; end; TFooReadJson = class private [ JsonName( 'number_read' ) ] FNumber: Integer; public property Number: Integer read FNumber write FNumber; end; type TJsonSerializer = class abstract private type TConverter = record ClassType: TClass; Convert: TFunc<TObject, TObject>; end; private FConverterMap: TDictionary<TClass, TConverter>; FReverterMap : TDictionary<TClass, TConverter>; protected procedure RegisterConverter<TSource: class; TResult: class>( Converter: TFunc<TSource, TResult> ); procedure RegisterConverterReverter<TSource: class; TResult: class, constructor>( Converter: TFunc<TSource, TResult>; Reverter: TFunc<TResult, TSource> ); procedure RegisterReverter<TSource: class; TResult: class, constructor>( Converter: TFunc<TResult, TSource> ); public constructor Create; virtual; destructor Destroy; override; function Serialize<T: class>( AObject: T ): string; function Deserialize<T: class>( const JsonStr: string ): T; end; type TConcreteSerializer = class( TJsonSerializer ) public constructor Create; virtual; end; implementation uses REST.Json, System.Json; { TJsonSerializer } constructor TJsonSerializer.Create; begin inherited; FConverterMap := TDictionary<TClass, TConverter>.Create; FReverterMap := TDictionary<TClass, TConverter>.Create; end; function TJsonSerializer.Deserialize<T>( const JsonStr: string ): T; var lConverter: TConverter; lJson : TJsonObject; lSerObj : TObject; begin if not FReverterMap.TryGetValue( T, lConverter ) then raise Exception.Create( 'Fehlermeldung' ); lJson := TJsonObject.ParseJSONValue( JsonStr ) as TJsonObject; try lSerObj := lConverter.ClassType.Create; try TJson.JsonToObject( lSerObj, lJson ); Result := lConverter.Convert( lSerObj ) as T; finally lSerObj.Free; end; finally lJson.Free; end; end; destructor TJsonSerializer.Destroy; begin FConverterMap.Free; FReverterMap.Free; inherited; end; procedure TJsonSerializer.RegisterConverter<TSource, TResult>( Converter: TFunc<TSource, TResult> ); var lConverter: TConverter; begin lConverter.ClassType := TResult; lConverter.Convert := function( Source: TObject ): TObject begin Result := Converter( Source as TSource ); end; FConverterMap.Add( TSource, lConverter ); end; procedure TJsonSerializer.RegisterConverterReverter<TSource, TResult>( Converter: TFunc<TSource, TResult>; Reverter: TFunc<TResult, TSource> ); begin RegisterConverter<TSource, TResult>( Converter ); RegisterReverter<TSource, TResult>( Reverter ); end; procedure TJsonSerializer.RegisterReverter<TSource, TResult>( Converter: TFunc<TResult, TSource> ); var lConverter: TConverter; begin lConverter.ClassType := TResult; lConverter.Convert := function( Source: TObject ): TObject begin Result := Converter( Source as TResult ); end; FReverterMap.Add( TSource, lConverter ); end; function TJsonSerializer.Serialize<T>( AObject: T ): string; var lConverter: TConverter; lSerObj : TObject; begin if not FConverterMap.TryGetValue( AObject.ClassType, lConverter ) then raise Exception.Create( 'Fehlermeldung' ); lSerObj := lConverter.Convert( AObject ); try Result := TJson.ObjectToJsonString( lSerObj ); finally lSerObj.Free; end; end; { TConcreteSerializer } constructor TConcreteSerializer.Create; begin inherited; RegisterConverter<TFooData, TFooWriteJson>( function( s: TFooData ): TFooWriteJson begin Result := TFooWriteJson.Create; Result.Number := IntToStr( s.Number ); end ); RegisterReverter<TFooData, TFooReadJson>( function( s: TFooReadJson ): TFooData begin Result := TFooData.Create; Result.Number := s.Number; end ); end; end.
Delphi-Quellcode:
procedure Test;
var lSer : TJsonSerializer; lfoo : TFooData; lData: string; begin lSer := TConcreteSerializer.Create; try lfoo := TFooData.Create; try lfoo.Number := 42; lData := lSer.Serialize( lfoo ); finally lfoo.Free; end; WriteLn( lData ); // {"number_write":"42"} lData := '{"number_read":42}'; lfoo := lSer.Deserialize<TFooData>( lData ); try WriteLn( lfoo.Number ); finally lfoo.Free; end; finally lSer.Free; end; end; |
AW: RestServer Antwort Json ohne "[" Klammern
![]() In diesem Vido wird beschrieben das auf einem Rest Server
Delphi-Quellcode:
TJSONObject als Result dienen kann.
function EchoJson: TJSONObject;
Es wird mittels
Delphi-Quellcode:
allerdings findet sich logischerweise nirgends ein .free.
Result := TJSONObject.create erzeugt
Meine Frage an die Profis ist nun ob ich das so auch gefahrlos in jeder function so verwenden kann. Ich erinnere mich an TStringlisten als result, die dann Leaks erzeugt haben. Grüße SM;) |
AW: RestServer Antwort Json ohne "[" Klammern
Natürlich erzeugt das ein MemLeak, wenn du das nicht entsprechend behandlest und beim Aufruf der Funktion auch die LifeTime-Management-Verantwortung für das Ergebnis übernimmst.
Ist exakt das Gleiche wie bei
Delphi-Quellcode:
Es gibt noch einen kleinen Unterschied:
function BuildObject : TObject;
begin Result := TObject.Create; end; var lObj: TObject; begin TObject.Create; // <= MemLeak BuildObject(); // <= MemLeak; // keine MemLeaks mit lObj := TObject.Create; try // ... finally lObj.Free; end; lObj := BuildObject(); try // ... finally lObj.Free; end; end; Wenn beim Erzeugen der Instanz ein Problem auftritt, dann soll man auch dafür sorgen, dass die Instanz aufgeräumt wird (so wie das auch der
Delphi-Quellcode:
macht);
constructor
Delphi-Quellcode:
function BuildObject: TObject;
begin Result := TObject.Create; // <= Bei einer Excpetion gibt es keine Instanz try // hier noch beim Result-Object weitere Eigenschaften setzen // hier könnte es zu einer Exception kommen except Result.Free; // <= bei einer Exception, wird die Instanz verworfen raise; // <= und die Exception wieder ausgelöst end; end; |
AW: RestServer Antwort Json ohne "[" Klammern
Perfect!! Danke für die Antwort. Das sind immer diese Fehlerteufel wenn man es nicht beachtet und dann das Wundern losgeht.
Gruß SM;) |
AW: RestServer Antwort Json ohne "[" Klammern
Dann könnte die function so aussehen
Delphi-Quellcode:
Einwände?
function TServerMethods1.updateHddCrawler(Key: string; aJSONObject: TJSONObject): TJSONObject;
var LJSONObject: TJSONObject; s: string; begin Result := TJSONObject.Create; try if KeyValidation(Key) then frmHddCrawler.AnalyzeJson(aJSONObject,Result) else Result.AddPair('error', 'invalid key') ; except Result.Free; raise; end; end; |
AW: RestServer Antwort Json ohne "[" Klammern
Was die Erzeugung der Result-Instanz angeht -> Nein.
Der Rest sieht seltsam aus :stupid: |
AW: RestServer Antwort Json ohne "[" Klammern
Jap! Zum Testen an sich nutze ich gerne Formen. Vor allem in der Planung. Dann kann ich mir auch mal per button Inhalte ausgeben lassen, oder auch mal eine kleine Testroutine einpflegen.
Oder meintest du was anderes? |
AW: RestServer Antwort Json ohne "[" Klammern
Auch ...
Du willst doch etwas konkretes
Delphi-Quellcode:
erledigen und übergibst dafür irgendwas
frmHddCrawler.Analyze
Delphi-Quellcode:
.
TJSONObject
Delphi-Quellcode:
Wer jetzt den
ICrawlHdd = interface
function Analyze( request : THddCrawlerRequest ) : THddCrawlerResponse; end; function TServerMethods1.updateHddCrawler(Key: string; aJSONObject: TJSONObject): TJSONObject; var request: THddCrawlerRequest; response: THddCrawlerResponse; error : TErrorResponse; begin // Prüfung ob die Daten im Json zum Aufruf passen request := TJson.JsonToObject<THddCrawlerRequest>( aJSONObject ); try if KeyValidation(Key) then begin // Dienst fragen response := HddCrawlerService.Analyze( request ); try // Ergebnis in Json umwandeln Result := TJson.ObjectToJsonObject( response ); finally response.Free; end; end else begin error := TErrorResponse.Create( 'invalid key' ); try Result := TJson.ObjectToJsonObject( error ); finally error.Free; end; end; finally request.Free; end; end;
Delphi-Quellcode:
genau ausführt, kann dir egal sein. Und ob die Daten irgenwann mal per JSON gekommen sind, ist dem Service jetzt auch egal. Der brauchst also kein JSON mehr zu kennen.
ICrawlHdd
Als Service kannst du auch eine Form verwenden:
Delphi-Quellcode:
THddCrawlerForm = class( TForm, ICrawlHdd )
private { ICrawlHdd } function Analyze( request: THddCrawlerRequest ): THddCrawlerResponse; end; |
AW: RestServer Antwort Json ohne "[" Klammern
Ja das macht Sinn THX :)
Gruß SM;) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz