POST REQUEST JSON File ABAP

Getting started ... Alles für einen gelungenen Start.
16 Beiträge • Seite 1 von 2 (current) Nächste
16 Beiträge Seite 1 von 2 (current) Nächste

POST REQUEST JSON File ABAP

Beitrag von sap_koun (ForumUser / 29 / 24 / 0 ) »
hi zusammen,

ich habe die erste Zeile einer internen Tabelle ins JSON-Format gebracht und in der Variable lv_json festgehalten.

Jetzt würde ich gerne den Inhalt (also lv_json) mittels POST Request in der Klasse cl_http_client versenden.

Wie schreibe ich das?

mein Versuch:

Code: Alles auswählen.

DATA: lt_zinvoice TYPE TABLE OF ty_zinvoice,
      lv_json     TYPE string.

SELECT  invoice_ID , paymeth, price, currency FROM ZINVOICE_TAB_2 INTO TABLE @lt_zinvoice UP TO 1 ROWS.

  /ui2/cl_json=>serialize(
      EXPORTING
        data          = lt_zinvoice
        pretty_name   = /ui2/cl_json=>pretty_mode-camel_case
      RECEIVING
        r_json = lv_json ).

WRITE / lv_json.


WRITE / lv_json.

*send JSON away

" Create client
cl_http_client=>create_by_url(
  EXPORTING
    url                = 'https://xxxxxxx.xxxxxxxxx'
  IMPORTING
    client             = DATA(lo_client)
  EXCEPTIONS
    argument_not_found = 1
    plugin_not_active  = 2
    internal_error     = 3
    OTHERS             = 4 ).

" Prepare request
lo_client->request->set_method( if_http_request=>co_request_method_post ).
lo_client->request->set_form_field( lv_json ).

gesponsert
Stellenangebote auf ABAPforum.com schalten
kostenfrei für Ausbildungsberufe und Werksstudenten


Re: POST REQUEST JSON File ABAP

Beitrag von a-dead-trousers (Top Expert / 4395 / 223 / 1182 ) »

Code: Alles auswählen.

lo_client->request->set_data( ... ).

Folgende Benutzer bedankten sich beim Autor a-dead-trousers für den Beitrag:
sap_koun

Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: POST REQUEST JSON File ABAP

Beitrag von sap_koun (ForumUser / 29 / 24 / 0 ) »
Hi a-dead-trousers,

vielen Dank für deine Hilfe.

Ich bekomme nun folgenden Fehler

Code: Alles auswählen.

http_status_code: 415
status_text: Unsupported Media Type
Ich vermute es liegt an den eckigen Klammern, die die Klasse/Methode /ui2/cl_json=>serialize an den JSON-String hinzufügt.

Eine Idee, wie man das umgeht?

Re: POST REQUEST JSON File ABAP

Beitrag von sap_koun (ForumUser / 29 / 24 / 0 ) »
Konnte es lösen:

Das musste dem Header mitgegeben werden.

Code: Alles auswählen.

o_client->request->set_header_field( name  = 'Content-Type' value = 'application/json' )

nächstes problem:

Code: Alles auswählen.


unprocessable entity

hat wohl mit der JSON-Struktur zutun, die ich absende.

wenn ihr noch einen tipp habt, gerne.

grüße

Re: POST REQUEST JSON File ABAP

Beitrag von a-dead-trousers (Top Expert / 4395 / 223 / 1182 ) »
Alternativ zu

Code: Alles auswählen.

o_client->request->set_header_field( name  = 'Content-Type' value = 'application/json' )
gäbe es auch noch

Code: Alles auswählen.

o_client->request->set_content_type( content_type = 'application/json' )
Was den Fehler anbelangt, hast du die Zeile

Code: Alles auswählen.

lo_client->request->set_form_field( lv_json ).
noch in deinem code?
Wenn ja würde ich die mal rausnehmen, weil soweit ich weiß darf man nur SET_FORM_FIELD oder SET_DATA bzw. SET_CDATA verwenden und nicht beides.

Ach ja, ist mir gerade erst aufgefallen, wenn du einen JSON-STRING und nicht XSTRING hast musst du SET_CDATA und nicht SET_DATA verwenden.
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: POST REQUEST JSON File ABAP

Beitrag von sap_koun (ForumUser / 29 / 24 / 0 ) »
hi @a-dead-trousers,

ich bekomme immernoch den Fehler 422 in allen drei Varianten:

Code: Alles auswählen.

http_status_code: 422
status_text: Unprocessable Entity
Der Code:

Code: Alles auswählen.

DATA: lt_zinvoice TYPE TABLE OF ty_zinvoice,
      lv_json     TYPE xstring.

...

* set http method
o_client->request->set_method( if_http_request=>co_request_method_post ).
o_client->request->set_header_field( name  = 'Content-Type' value = 'application/json' ).
o_client->request->set_data( lv_json ).



Mit der folgenden Variante kommt auch der "422 Unprocessable Entity" Fehler.

DATA: lt_zinvoice TYPE TABLE OF ty_zinvoice,
lv_json TYPE string.

und

o_client->request->set_form_field( name = 'data' value = lv_json ).


und Variante Nummer Drei kommt auch der 422 Fehler.

lv_json TYPE string.

und

o_client->request->set_cdata( lv_json ).

Noch eine Idee?

EDIT:

Mit dem API-Testtool funktioniert es mit derselben JSON-Datei (und selber Inhalt. Ich kann immer wieder dasselbe reinsenden und bekomme eine Antwort). Es kann also eigentlich nicht am Inhalt liegen.

Es muss irgendwas SAP-spezifisches sein. :(


lg

Re: POST REQUEST JSON File ABAP

Beitrag von fr-g (ForumUser / 76 / 12 / 25 ) »
Hast du mal probiert, die Protokollversion mitzugeben?
Zum Beispiel 1.1:

Code: Alles auswählen.

lo_client->request->set_version( if_http_request=>co_protocol_version_1_1 ).
Von dem, was ich mir aus den Code-Schnipseln zusammenreimen kann, könnte es trotzdem auch immer noch am Format liegen. Aber wenn du sagst, LV_JSON entspricht nach dem SERIALIZE genau der gewünschten Nachricht, dann liegt es vermutlich doch noch an den Request-Parametern...

Folgende Benutzer bedankten sich beim Autor fr-g für den Beitrag:
sap_koun


Re: POST REQUEST JSON File ABAP

Beitrag von sap_koun (ForumUser / 29 / 24 / 0 ) »
Hi, es funktioniert, ich bekomme ein JSON-File zurück. Es lag an der Struktur der Datei. Es hat ein Key-Value pair gefehlt, die angesprochene API hat etwas anderes erwartet.

Re: POST REQUEST JSON File ABAP

Beitrag von sap_koun (ForumUser / 29 / 24 / 0 ) »
Hey,
ich bekomme nun die JSON-File zurück.

Ich würde gerne einen bestimmen Value eines bestimmten Key-Value Pairs in eine Variable packen und z.B. innerhalb einer Nachricht/Message ausgeben.

Hier der Part, wo ich mit der Response umgehe:

Code: Alles auswählen.

o_client->receive( ).
Data: lv_http_status type i,
      lv_status_text type string.

o_client->response->get_status( IMPORTING
                                  code = lv_http_status
                                  reason = lv_status_text ).

write: / 'http_status_code:', lv_http_status.
write: / 'status_text:', lv_status_text.

if lv_http_status = 200.
  Data(lv_result) = o_client->response->get_cdata( ).
  write: / 'Response:'.
  write: / lv_result.
endif.

* close http connection
o_client->close( ).
endif.

CATCH cx_root INTO DATA(e_txt).
    WRITE: / e_txt->get_text( ).
ENDTRY.

message 'Your ID is' && *variable für ID*? type 'i'.
Aktuell bekomme ich entweder gar nichts hinter "Your ID is" oder den kompletten String.

Habt ihr eine Idee, wie ich das umsetzen könnte?

Meine Idee:
Den String erstmal deserialisieren, und in eine Tabelle packen.
Und dann genau diesen einen Wert aus der Tabelle rausgeben?

Oder lieber wie hier beschrieben?

https://blogs.sap.com/2021/06/27/json-t ... -and-json/

Beispielcode:

Code: Alles auswählen.

...

if lv_http_status = 200.
  Data(lv_result) = o_client->response->get_cdata( ).
  write: / 'Response:'.
  write: / lv_result.

  DATA(json) = o_client->response->get_cdata( ).
  ...
endif.


Re: POST REQUEST JSON File ABAP

Beitrag von sap_koun (ForumUser / 29 / 24 / 0 ) »
Um es einfacher zu machen, ein ausführbares Beispiel mit vorhandenen Daten im SAP.

Code: Alles auswählen.

DATA gv_json_output TYPE string.
SELECT carrid, connid, fldate, price
  FROM  sflight
  INTO TABLE @DATA(it_sflight)
  UP TO 4 ROWS.

**JSON converter class - Method -> Serialize method to convert data in JSON
gv_json_output =
/ui2/cl_json=>serialize(
data = it_sflight
compress = abap_true pretty_name = /ui2/cl_json=>pretty_mode-camel_case ).

**Now check JSON output converted format
cl_demo_output=>display( gv_json_output ).



TYPES: BEGIN OF str_sflight_input,
         carrid TYPE s_carr_id,
         connid TYPE s_conn_id,
         fldate TYPE s_date,
         price  TYPE s_price,
       END OF str_sflight_input.

DATA itb_sflight_input TYPE STANDARD TABLE OF str_sflight_input.

CLEAR itb_sflight_input[].
**JSON converter class - Method -> Deserialize convert JSON string data into internal table
/ui2/cl_json=>deserialize(
  EXPORTING json = gv_json_output
  pretty_name = /ui2/cl_json=>pretty_mode-camel_case
  CHANGING data = itb_sflight_input ).

**Internal table filled from JSON input data
cl_demo_output=>display( itb_sflight_input ).



*SELECT itb_sflight_input~carrid, itb_sflight_input~connid, itb_sflight_input~price
*       FROM @itb_sflight_input AS itb_sflight_input INTO message.

"
Data(carrid)    = carrid type string.
Data(lv_number) = carrid.
Data(lv_string) = 'Test'.
  message I000(Z_MESSAGE_BALANCE) with lv_number lv_string.
Wie nehme ich z.B. den Wert carrid aus der ersten Zeile der Tabelle,
und gebe ihn der Message mit?

Re: POST REQUEST JSON File ABAP

Beitrag von fr-g (ForumUser / 76 / 12 / 25 ) »
Ich würde mir eine Klasse schreiben, die die Response repräsentiert. Meistens (de)serialisiere ich mit einer kleinen Simple Transformation.
Aber, wenn du nur an einen einzelnen Wert dran willst, könnte es mit SXML einfacher gehen, z.B. so in etwa:

Code: Alles auswählen.

    "oder dein präferierter Reader...
    DATA(lo_reader) = cl_sxml_string_reader=>create( cl_abap_codepage=>convert_to( lv_dein_json ) ).

    DO.
      DATA(lo_node) = lo_reader->read_next_node( ).
      IF lo_node IS INITIAL.
        EXIT.
      ENDIF.

      IF lo_node->type = if_sxml_node=>co_nt_element_open.
        "JSON-Objektbezeichner sind als Attribut 'name' dargestellt
        DATA(lo_value) = CAST if_sxml_open_element( lo_node )->get_attribute_value( `name` ).

        "Bezeichner des Keys
        IF lo_value IS BOUND AND lo_value->get_value( ) = `id`.
          DATA(lo_value_node) = CAST if_sxml_value( lo_reader->read_next_node( ) ).
          "der Wert zum Key
          DATA(lv_id_value) = lo_value_node->get_value( ).
          EXIT.
        ENDIF.
      ENDIF.

    ENDDO.
Das nur als schnelles Beispiel zusammengehackt :)

Edit: Hab dein Beispiel erst nach meinem Post gesehen. Aber da geht es doch gar nicht mehr ums Parsen vom JSON, oder?! Die erste Zeile deiner itab kannst du ja einfach auslesen.

Folgende Benutzer bedankten sich beim Autor fr-g für den Beitrag:
sap_koun


Re: POST REQUEST JSON File ABAP

Beitrag von sap_koun (ForumUser / 29 / 24 / 0 ) »
Hey, danke für das Beispiel und die schnelle Antwort.

und dann nehme ich die Variable lv_id_value, richtig?

Code: Alles auswählen.

message I000(Z_MESSAGE_TEST) with lv_id_value.
so?

Hast du auch ein Beisiel für die Deserialisierung? eine Vorlage oder so? Mehrere Werte kommen auch noch auf mich zu.

Re: POST REQUEST JSON File ABAP

Beitrag von fr-g (ForumUser / 76 / 12 / 25 ) »
Ja, zu lv_id_value.
Das Beispiel ist eine Deserialisierung ;) Und es passt natürlich auch nur für den Fall, dass der Bezeichner "id" eindeutig in der ganzen Datei ist.

Folgende Benutzer bedankten sich beim Autor fr-g für den Beitrag:
sap_koun


Re: POST REQUEST JSON File ABAP

Beitrag von sap_koun (ForumUser / 29 / 24 / 0 ) »
Vielen Dank, ich werde es versuchen und das Ergebnis posten.

Hast du auch ein Beispiel für "ganz normal" für Beginner mit einer Tabelle?
Was muss ich hinter Select schreiben?

Code: Alles auswählen.

DATA wa TYPE spfli.

SELECT *ein bestimmtes Feld in einer Tabelle anvisieren und in einen String umwandeln zur Ausgabe*.

READ TABLE str_sflight_input

Data(carrid)    = carrid type string.
Data(lv_number) = carrid.
Data(lv_string) = 'Test'.
  message I000(Z_MESSAGE_BALANCE) with lv_number lv_string.

Re: POST REQUEST JSON File ABAP

Beitrag von sap_koun (ForumUser / 29 / 24 / 0 ) »
fr-g hat geschrieben:
25.01.2023 16:38
Ja, zu lv_id_value.
Das Beispiel ist eine Deserialisierung ;) Und es passt natürlich auch nur für den Fall, dass der Bezeichner "id" eindeutig in der ganzen Datei ist.

Hi fr-g,

ich bekomme folgende Fehlermeldung:

Code: Alles auswählen.

Quelltyp \Class=CL_SXML-OPEN_ELEMENT ist nicht zuweisungskompatibel zu Zieltyp \INTERFACE=IF_SXML_VALUE."

Vergleichbare Themen

5
Antw.
709
Views
POST Request mit "Eingabemaske" an eine REST API
von sap_koun » 06.06.2022 13:04 • Verfasst in ABAP® für Anfänger
2
Antw.
4245
Views
HTTP-Post von Dateien in ABAP
von Abrissbirne » 17.09.2012 01:44 • Verfasst in ABAP® Core
0
Antw.
1762
Views
ABAP HTTP-Request
von tohe » 05.02.2015 10:38 • Verfasst in ABAP® für Anfänger
1
Antw.
1688
Views
XML File vom UNIX Server in ABAP aufrufen
von axel.mohnen » 14.06.2006 09:08 • Verfasst in ABAP® Core
3
Antw.
16260
Views
URL File-Server Internet File Download /Delet cl_http_client
von Luigi91 » 04.10.2016 08:28 • Verfasst in ABAP Objects®

Newsletter Anmeldung

Keine Beiträge verpassen! Wöchentlich versenden wir lesenwerte Beiträge aus unserer Community.
Die letzte Ausgabe findest du hier.
Details zum Versandverfahren und zu Ihren Widerrufsmöglichkeiten findest du in unserer Datenschutzerklärung.

Unbeantwortete Forenbeiträge

Daten an Tabelle binden
Gestern von Bright4.5 1 / 516
aRFC im OO-Kontext
vor 4 Wochen von ralf.wenzel 1 / 2149
Hilfe bei SWEC/SWE2
letzen Monat von retsch 1 / 8744