Skip to Content

This can be considered a continuation of the earlier Blog Post i have written Consume Odata Service in ABAP CL_HTTP_CLIENT->CREATE_BY_DESTINATION. In the earlier post it is described how to trigger a GET method of the Odata Service.

This post would not have been possible if not for the wonderful Community that is SCN. Thank You Wouter Venhuizen , Thomas Schmidt and Ashwin Dutt Rfor your cotributions. i would Award you more than 10 Points if i could. For pointing me in the right Direction. Without this i would still be stumbling, lost in the Wildlands of SCN.

Calling https web service POST method from ABAP | SCN.

Even though each question and answer I find may not be particular to the issue i am facing, it always help me channel my investigation in the right direction.

I hope this blog Post does the same.

The Requirement:

We had a recent requirement in our team where we were required to modify some Data in the HANA system from ECC.

There was already a HANA service that we being used by the UI to create the same data, So the solution direction was to use the same service to post Data from ECC to HANA.

The Solution:

The approach was to call a HTTP Post method from ECC using the CL_HTTP_CLIENT class.

the process is the same for instantiating a HTTP Client has already been described in my earlier blog.

The Difference between a GET method and the Post Method for Odata is the X-CSRF token handling.

Since the HTTP POST method is a modifying call, an X-CSRF Token has to be passed for security purposes.

More information on this Topic in the below Link

Cross-Site Request Forgery Protection – SAP Gateway Foundation (SAP_GWFND) – SAP Library

In one of the posts i saw related to this topic on SCN(usage of CSRF token in ABAP report for POST request), the Classes being used were unavailable in ECC because in our landscape the ECC and GATEWAY implementations are on two separate systems.

in the Above post once the X-CSRF Token is fetched the REST object and the HTTP Client are refreshed.

They are re instantiated and then the Token is used in a HTTP POST request. this for some reason was not working when i was using the Class Methods available for CL_HTTP_CLIENT.

the Work around implemented, was to use the same object instantiation for both the GET and POST methods.

  1. Instantiate the Client
  2. Fill headers and set the URI for the GET request of the same Entity for which we want to POST.
    1. While filling the headers we have to pass a header Field with name ‘X-CSRF-Token’ and value ‘Fetch’.
  3. Trigger the  HTTP GET request,
    1. The X-CSRF token can be retrieved from the Response attribute of the HTTP Client object.
  4. Fill the headers of the request Attribute once again. but this time we set the X-CSRF token with the value retrieved from step 3, instead of “Fetch”.
    1. Set the Request HTTP method to POST
    2. Fill the BODY of the HTTP request with the data that has to be modified
    3. Trigger the HTTP post request

Note: In between step 3 and 4 we should not refresh the HTTP Client Object that was used to fetch the X-CSRF token.

          



Detailed Code for above Steps:-

Preparatory Step:- Create RFC destination in SM59


(please refer to Step 1 in my earlier post) Consume Odata Service in ABAP CL_HTTP_CLIENT->CREATE_BY_DESTINATION.

Step1:- Instantiate the HTTP Client in ABAP


DATA:  l_query TYPE string,

       l_body TYPE string,

       l_token TYPE string,       

       l_result TYPE string.

DATA: lo_http_client TYPE REF TO if_http_client.

CONSTANTS:  c_rfchana   TYPE rfcdest VALUE ‘RFCHANA’, ” RFC Destination

            c_query     TYPE string VALUE ‘/ModifyMaterial’. ” Entity name

.

* fetch X-CSRF token

DATA: l_query TYPE string.    ” URI Query


DATA: lo_http_client TYPE REF TO if_http_client.

* Create the HTTP CLient

  CALL METHOD cl_http_client=>create_by_destination

    EXPORTING

      destination              = C_RFCHANA

    IMPORTING

      client                   = lo_http_client

    EXCEPTIONS

      argument_not_found       = 1

      destination_not_found     = 2

      destination_no_authority = 3

      plugin_not_active            = 4

      internal_error                   = 5

      OTHERS                          = 6.

  IF NOT sy-subrc IS INITIAL.

  ENDIF.

STEP 2:- Fill headers and set URI for GET Method

* create the URI for the client.

  l_query = im_query.

  CALL METHOD cl_http_utility=>set_request_uri

    EXPORTING

      request = lo_http_client->request

      uri     = l_query.

* update the HTTP Method

  CALL METHOD lo_http_client->request->set_method

    EXPORTING

      method = lo_http_client->request->co_request_method_get.

* set Content type

  CALL METHOD lo_http_client->request->if_http_entity~set_content_type

    EXPORTING

      content_type =  ‘application/json’.

* set header field for fetching X-CSRF token

  CALL METHOD lo_http_client->request->set_header_field

    EXPORTING

      name  = ‘X-CSRF-Token’

      value = ‘Fetch’.

Step 3:- Trigger the GET Method

  lo_http_client->send(

      EXCEPTIONS

        http_communication_failure = 1

        http_invalid_state         = 2 ). “Send the HTTP request

  lo_http_client->receive(

    EXCEPTIONS

      http_communication_failure = 1

      http_invalid_state         = 2

      http_processing_failed     = 3 ). “receive the response

****GET x-csrf TOKEN from earlier response

CALL METHOD lo_http_client->response->get_header_field

  EXPORTING

    name  = ‘X-CSRF-Token’

  RECEIVING

    value = l_token.

Step 4:- Fill headers and Body for HTTP POST method

* Set X-CSRF- Token in the new request.

CALL METHOD lo_http_client->request->set_header_field

  EXPORTING

    name  = ‘X-CSRF-Token’

    value = l_token.

* update the HTTP Method

CALL METHOD lo_http_client->request->set_method

  EXPORTING

    method = lo_http_client->request->co_request_method_post.

****content type

CALL METHOD lo_http_client->request->set_content_type

  EXPORTING

    content_type = ‘application/json’.

* create Body for the HTTP Post request

CALL METHOD lo_http_client->request->set_cdata

  EXPORTING

    data = l_body.

lo_http_client->send(

    EXCEPTIONS

      http_communication_failure = 1

      http_invalid_state         = 2 ). “Send the HTTP request

lo_http_client->receive(

  EXCEPTIONS

    http_communication_failure = 1

    http_invalid_state         = 2

    http_processing_failed     = 3 ). “receive the response

l_result = lo_http_client->response->get_cdata( ).

This Succesfully posts my data to HANA, and i can read the status code in the response header to check the request status.

Do let me know if this was helpful, as usual i am always available in case you need any further clarifications.

Kind regards,

Vamsi


To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply