CLASS zrest_cl_defs DEFINITION
PUBLIC
CREATE PUBLIC .
PUBLIC SECTION.
CONSTANTS c_state_success TYPE char1 VALUE 'S' ##NO_TEXT.
CONSTANTS c_state_warning TYPE char1 VALUE 'W' ##NO_TEXT.
CONSTANTS c_state_error TYPE char1 VALUE 'E' ##NO_TEXT.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS ZREST_CL_DEFS IMPLEMENTATION.
ENDCLASS.
CLASS zrest_cl_model DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS get_datetime
EXPORTING
!response_body TYPE zrest_s_response-body
!state TYPE zrest_s_response-state .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS ZREST_CL_MODEL IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZREST_CL_MODEL->GET_DATETIME
* +-------------------------------------------------------------------------------------------------+
* | [<---] RESPONSE_BODY TYPE ZREST_S_RESPONSE-BODY
* | [<---] STATE TYPE ZREST_S_RESPONSE-STATE
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD get_datetime.
DATA: exref TYPE REF TO cx_root.
TRY .
TYPES : BEGIN OF ty_res,
datetime TYPE tzntimestp,
END OF ty_res.
DATA: res TYPE ty_res.
res-datetime = sy-datum && sy-uzeit.
response_body = /ui2/cl_json=>serialize( EXPORTING data = res ).
state-state = zrest_cl_defs=>c_state_success.
CATCH cx_root INTO exref.
state-state = zrest_cl_defs=>c_state_error.
state-state_text = exref->get_text( ).
ENDTRY.
ENDMETHOD.
ENDCLASS.
CLASS zrest_cl_req_controller DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS process_request
IMPORTING
!req_json TYPE string
EXPORTING
!response_json TYPE string
!response_stc TYPE zrest_s_response .
PROTECTED SECTION.
PRIVATE SECTION.
CONSTANTS:
c_req_get_datetime TYPE zrest_e_req_id VALUE '1001'.
METHODS conv_stc_to_json
IMPORTING
response_stc TYPE zrest_s_response
RETURNING VALUE(result) TYPE string.
ENDCLASS.
CLASS ZREST_CL_REQ_CONTROLLER IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZREST_CL_REQ_CONTROLLER->CONV_STC_TO_JSON
* +-------------------------------------------------------------------------------------------------+
* | [--->] RESPONSE_STC TYPE ZREST_S_RESPONSE
* | [<-()] RESULT TYPE STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD conv_stc_to_json.
DATA: exref TYPE REF TO cx_root.
TRY .
result = /ui2/cl_json=>serialize( EXPORTING data = response_stc ).
CATCH cx_root.
result = exref->get_text( ).
ENDTRY.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZREST_CL_REQ_CONTROLLER->PROCESS_REQUEST
* +-------------------------------------------------------------------------------------------------+
* | [--->] REQ_JSON TYPE STRING
* | [<---] RESPONSE_JSON TYPE STRING
* | [<---] RESPONSE_STC TYPE ZREST_S_RESPONSE
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD process_request.
DATA: exref TYPE REF TO cx_root.
TRY .
DATA req_stc TYPE zrest_s_request.
/ui2/cl_json=>deserialize(
EXPORTING
json = req_json
CHANGING
data = req_stc
).
IF req_stc-id IS NOT INITIAL.
DATA(model) = NEW zrest_cl_model( ).
IF req_stc-id EQ c_req_get_datetime.
model->get_datetime(
IMPORTING
response_body = response_stc-body
state = response_stc-state
).
ELSE.
response_stc-state-state = zrest_cl_defs=>c_state_warning.
MESSAGE s001(zrest_msg) INTO response_stc-state-state_text.
ENDIF.
ELSE.
"Fill dummy content as sample
req_stc-id = 999999.
req_stc-body = 'Some Json Content'.
response_stc-body = /ui2/cl_json=>serialize( EXPORTING data = req_stc ).
response_stc-state-state = zrest_cl_defs=>c_state_warning.
MESSAGE s002(zrest_msg) INTO response_stc-state-state_text.
ENDIF.
response_json = conv_stc_to_json( response_stc = response_stc ).
CATCH cx_root.
response_stc-state-state = zrest_cl_defs=>c_state_error.
response_stc-state-state_text = exref->get_text( ).
response_json = conv_stc_to_json( response_stc = response_stc ).
ENDTRY.
ENDMETHOD.
ENDCLASS.
CLASS zrest_cl_req_http_handler DEFINITION
PUBLIC
INHERITING FROM cl_rest_resource
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS if_rest_resource~get
REDEFINITION .
METHODS if_rest_resource~post
REDEFINITION .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS ZREST_CL_REQ_HTTP_HANDLER IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZREST_CL_REQ_HTTP_HANDLER->IF_REST_RESOURCE~GET
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD if_rest_resource~get.
DATA(req_json) = mo_request->get_uri_query_parameter( iv_name = 'req' iv_encoded = abap_false ).
DATA(controller) = NEW zrest_cl_req_controller( ).
controller->process_request(
EXPORTING
req_json = req_json
IMPORTING
response_json = DATA(response_json)
).
mo_response->create_entity( )->set_string_data( iv_data = response_json ).
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZREST_CL_REQ_HTTP_HANDLER->IF_REST_RESOURCE~POST
* +-------------------------------------------------------------------------------------------------+
* | [--->] IO_ENTITY TYPE REF TO IF_REST_ENTITY
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD if_rest_resource~post.
DATA(req_json) = mo_request->get_entity( )->get_string_data( ).
DATA(controller) = NEW zrest_cl_req_controller( ).
controller->process_request(
EXPORTING
req_json = req_json
IMPORTING
response_json = DATA(response_json)
).
mo_response->create_entity( )->set_string_data( iv_data = response_json ).
ENDMETHOD.
ENDCLASS.
class ZREST_CL_HTTP_HANDLER definition
public
inheriting from CL_REST_HTTP_HANDLER
create public .
public section.
"Provides routing. Routing paths are assigned to controllers in this method
methods IF_REST_APPLICATION~GET_ROOT_HANDLER
redefinition .
protected section.
"If you want to disable, redefine that method. Just as an empty method.
methods HANDLE_CSRF_TOKEN
redefinition .
PRIVATE SECTION.
ENDCLASS.
CLASS ZREST_CL_HTTP_HANDLER IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZREST_CL_HTTP_HANDLER->HANDLE_CSRF_TOKEN
* +-------------------------------------------------------------------------------------------------+
* | [--->] IO_CSRF_HANDLER TYPE REF TO IF_REST_CSRF_HANDLER
* | [--->] IO_REQUEST TYPE REF TO IF_REST_REQUEST
* | [--->] IO_RESPONSE TYPE REF TO IF_REST_RESPONSE
* +--------------------------------------------------------------------------------------</SIGNATURE>
method HANDLE_CSRF_TOKEN.
*CALL METHOD SUPER->HANDLE_CSRF_TOKEN
* EXPORTING
* IO_CSRF_HANDLER =
* IO_REQUEST =
* IO_RESPONSE =
* .
endmethod.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZREST_CL_HTTP_HANDLER->IF_REST_APPLICATION~GET_ROOT_HANDLER
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RO_ROOT_HANDLER TYPE REF TO IF_REST_HANDLER
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD if_rest_application~get_root_handler.
"Provides routing.
"Service path /sap/bc/rest
"Sample URL http://vhcalnplci:8000/sap/bc/rest/zrest/Rest?sap-client=001&req={"ID":1001,"BODY":"Some Json Content"}
DATA(root_handler) = NEW cl_rest_router( ).
root_handler->attach(
EXPORTING
iv_template = '/Rest' " Unified Name for Resources
iv_handler_class = 'ZREST_CL_REQ_HTTP_HANDLER' " Object Type Name
).
* "You can add more request handler classes
* "Service path /sap/bc/rest
* "Sample URL http://vhcalnplci:8000/sap/bc/rest/zrest/Rest2?sap-client=001&req={"ID":1001,"BODY":"Some Json Content"}
* root_handler->attach(
* EXPORTING
* iv_template = '/Rest2' " Unified Name for Resources
* iv_handler_class = 'ZREST_CL_REQ_HTTP_HANDLER2' " Object Type Name
* ).
ro_root_handler = root_handler.
ENDMETHOD.
ENDCLASS.
CLASS zutil_cl_rest_ws DEFINITION
PUBLIC
CREATE PUBLIC .
"Class wrapper for making Rest Web Service Calls
PUBLIC SECTION.
"Constants
CONSTANTS : c_content_type_json TYPE string VALUE 'application/json; charset=utf-8',
c_content_type_xml TYPE string VALUE 'application/xml; charset=utf-8',
c_request_method_get TYPE string VALUE 'GET',
c_request_method_post TYPE string VALUE 'POST'.
"Makes WS Call
METHODS call_ws
IMPORTING
VALUE(i_url) TYPE string
VALUE(i_content_type) TYPE string DEFAULT c_content_type_json
VALUE(i_request_method) TYPE string DEFAULT c_request_method_get
VALUE(i_username) TYPE string OPTIONAL
VALUE(i_password) TYPE string OPTIONAL
VALUE(i_payload) TYPE string OPTIONAL
EXPORTING
VALUE(e_state) TYPE zutil_cl_defs=>gty_state
VALUE(e_response_str) TYPE string.
PROTECTED SECTION.
PRIVATE SECTION.
DATA http_client TYPE REF TO if_http_client.
METHODS fill_warning
RETURNING VALUE(state) TYPE zutil_cl_defs=>gty_state.
ENDCLASS.
CLASS ZUTIL_CL_REST_WS IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZUTIL_CL_REST_WS->CALL_WS
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_URL TYPE STRING
* | [--->] I_CONTENT_TYPE TYPE STRING (default =C_CONTENT_TYPE_JSON)
* | [--->] I_REQUEST_METHOD TYPE STRING (default =C_REQUEST_METHOD_GET)
* | [--->] I_USERNAME TYPE STRING(optional)
* | [--->] I_PASSWORD TYPE STRING(optional)
* | [--->] I_PAYLOAD TYPE STRING(optional)
* | [<---] E_STATE TYPE ZUTIL_CL_DEFS=>GTY_STATE
* | [<---] E_RESPONSE_STR TYPE STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD call_ws.
DATA: exref TYPE REF TO cx_root.
TRY.
"Using the this CREATE_BY_URL can simplify certain aspects of using this class
FREE http_client.
cl_http_client=>create_by_url(
EXPORTING
url = i_url
IMPORTING
client = http_client
EXCEPTIONS
argument_not_found = 1
plugin_not_active = 2
internal_error = 3
OTHERS = 4
).
IF sy-subrc <> 0.
e_state-state = fill_warning( ).
RETURN.
ENDIF.
" My logic originally used PUT, but you should be able to change to POST
http_client->request->set_method( i_request_method ).
http_client->request->set_content_type( i_content_type ).
" Remember to authenticate
IF i_username IS NOT INITIAL OR i_password IS NOT INITIAL.
http_client->authenticate(
username = i_username
password = i_password
).
ENDIF.
"If exists, prepare payload and assign
IF i_payload IS NOT INITIAL.
" Convert that payload to xstring.
DATA lv_payload_x TYPE xstring.
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
EXPORTING
text = i_payload
IMPORTING
buffer = lv_payload_x
EXCEPTIONS
failed = 1
OTHERS = 2.
IF sy-subrc <> 0.
e_state-state = zutil_cl_defs=>c_state_warning.
e_state-state = 'Encoding error!'.
RETURN.
ELSE.
http_client->request->set_data( lv_payload_x ). " Binary data
ENDIF.
ENDIF.
" Sending the request
http_client->send(
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2 ).
IF sy-subrc <> 0.
e_state-state = fill_warning( ).
RETURN.
ENDIF.
" Receiving the response
http_client->receive(
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3 ).
IF sy-subrc <> 0.
e_state-state = fill_warning( ).
RETURN.
ENDIF.
" Check the response. Hopefully you get back a JSON response.
e_response_str = http_client->response->get_cdata( ).
IF e_response_str IS INITIAL.
e_response_str = http_client->response->get_data( ).
ENDIF.
e_state-state = zutil_cl_defs=>c_state_success.
e_state-state_text = 'Successfully Completed.'.
CATCH cx_root INTO exref.
e_state-state = zutil_cl_defs=>c_state_error.
e_state-state_text = exref->get_text( ).
ENDTRY.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZUTIL_CL_REST_WS->FILL_WARNING
* +-------------------------------------------------------------------------------------------------+
* | [<-()] STATE TYPE ZUTIL_CL_DEFS=>GTY_STATE
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD fill_warning.
state-state = zutil_cl_defs=>c_state_warning.
http_client->get_last_error(
IMPORTING
message = DATA(msg)" Error Message
).
state-state_text = msg.
ENDMETHOD.
ENDCLASS.
CLASS zrest_cl_consumer DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS get_datetime
EXPORTING
state TYPE zutil_cl_defs=>gty_state
dt TYPE tzntimestp.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS ZREST_CL_CONSUMER IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZREST_CL_CONSUMER->GET_DATETIME
* +-------------------------------------------------------------------------------------------------+
* | [<---] STATE TYPE ZUTIL_CL_DEFS=>GTY_STATE
* | [<---] DT TYPE TZNTIMESTP
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD get_datetime.
"Sample method to consume rest web api
DATA: exref TYPE REF TO cx_root.
TRY.
"
CONSTANTS: c_uname TYPE string VALUE 'developer',
c_pass TYPE string VALUE 'Down1oad'.
"Build get call
DATA: url TYPE string VALUE 'http://vhcalnplci:8000/sap/bc/rest/zrest/Rest?sap-client=001'.
DATA req_stc TYPE zrest_s_request.
req_stc-id = '1001'.
DATA(req_json) = /ui2/cl_json=>serialize( EXPORTING data = req_stc ).
url = url && '&req=' && req_json.
"Call Web api
NEW zutil_cl_rest_ws( )->call_ws(
EXPORTING
i_url = url
i_username = c_uname
i_password = c_pass
IMPORTING
e_state = state
e_response_str = DATA(json_response)
).
IF state-state EQ zutil_cl_defs=>c_state_success.
DATA: resp_stc TYPE zrest_s_response.
/ui2/cl_json=>deserialize(
EXPORTING
json = json_response
CHANGING
data = resp_stc
).
IF resp_stc-state-state EQ zutil_cl_defs=>c_state_success.
TYPES : BEGIN OF ty_res,
datetime TYPE tzntimestp,
END OF ty_res.
DATA: resp_1001 TYPE ty_res.
/ui2/cl_json=>deserialize(
EXPORTING
json = resp_stc-body
CHANGING
data = resp_1001
).
dt = resp_1001-datetime.
ENDIF.
ENDIF.
CATCH cx_root INTO exref.
state-state = zutil_cl_defs=>c_state_error.
state-state_text = exref->get_text( ).
ENDTRY.
ENDMETHOD.
ENDCLASS.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
4 | |
3 | |
3 | |
2 | |
2 | |
2 | |
1 | |
1 | |
1 | |
1 |