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 SchmidtandAshwin 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.
- Instantiate the Client
- Fill headers and set the URI for the GET request of the same Entity for which we want to POST.
- While filling the headers we have to pass a header Field with name 'X-CSRF-Token' and value 'Fetch'.
- Trigger the HTTP GET request,
- The X-CSRF token can be retrieved from the Response attribute of the HTTP Client object.
- 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".
- Set the Request HTTP method to POST
- Fill the BODY of the HTTP request with the data that has to be modified
- 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