Skip to content

Instantly share code, notes, and snippets.

@caseahr
Created November 4, 2014 19:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save caseahr/125dfaac98f7ea3f6403 to your computer and use it in GitHub Desktop.
Save caseahr/125dfaac98f7ea3f6403 to your computer and use it in GitHub Desktop.
*&---------------------------------------------------------------------*
*& Report Z_REST_CALL2
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT Z_REST_CALL2.
TYPES: BEGIN OF ts_auth
, username TYPE string
, password TYPE string
, sid TYPE string
, END OF ts_auth
.
DATA: client_init TYPE REF TO if_http_client
, client_api TYPE REF TO if_http_client
, response TYPE REF TO if_http_response
, json TYPE string
* , json_doc TYPE REF TO zcl_json_document
, status TYPE string
, sid TYPE string
, server TYPE string
, auth TYPE ts_auth
, txt TYPE string.
types: begin of ty_hash,
ContractNumber type string,
b type i,
c type i,
end of ty_hash,
ty_hash_tab type standard table of ty_hash.
data: ls_deep type ty_hash,
ls_exp type ty_hash,
lt_deep type ty_hash_tab,
lt_exp type stringtab.
FIELD-SYMBOLS: <F1>, <F2>, <F3>.
cl_http_client=>create_by_url(
EXPORTING url = 'http://www.your-site.com/api/contract'
IMPORTING client = client_init
).
client_init->send( ).
client_init->receive( ).
json = client_init->response->get_cdata( ).
client_init->close( ).
*WRITE:/ json.
perform json_to_data using
'{"ContractNumber":"123444","b":2,"c":3}'
changing ls_exp.
ASSIGN ls_exp to <F1>.
DO 1 TIMES.
ASSIGN COMPONENT SY-INDEX OF STRUCTURE <F1> TO <F3>.
WRITE <F3>.
ENDDO.
*&---------------------------------------------------------------------*
*& Form json_to_data
*&---------------------------------------------------------------------*
form json_to_data using json type string changing data type any.
data: lv_off type i.
data: lv_len type i.
data: lv_key type string.
data: lv_value type string.
data: lv_char type char1. "Current chacater
data: lv_pchar type char1. "Previous character
data: lv_instr type boole_d. "Indicator: cursor in string
data: lv_level type i. "Depth inside a block
data: lv_table type boole_d.
field-symbols: <fk> type string.
field-symbols: <data> type any.
field-symbols: <table> type any table.
field-symbols: <sotab> type sorted table.
field-symbols: <sttab> type standard table.
field-symbols: <line> type any.
data: ls_line type ref to data.
data: lr_td type ref to cl_abap_typedescr.
data: lr_ttd type ref to cl_abap_tabledescr.
* If the incoming json contains no '{}[]', we are dealing with
* a basic (scalar) value that is simply assigned to the data
* and then we return
if json na '{}[]'.
* Replace escape characters (TODO: Check if there are more!)
lv_value = json.
replace all occurrences of '\n' in lv_value with cl_abap_char_utilities=>newline.
replace all occurrences of '\t' in lv_value with cl_abap_char_utilities=>horizontal_tab.
replace all occurrences of '\f' in lv_value with cl_abap_char_utilities=>form_feed.
replace all occurrences of '\v' in lv_value with cl_abap_char_utilities=>vertical_tab.
replace all occurrences of '\b' in lv_value with cl_abap_char_utilities=>backspace.
replace all occurrences of '\\' in lv_value with '\'.
* TODO: Deal with specific data types, e.g. dates etc.
data = lv_value.
exit.
endif.
lv_len = strlen( json ).
* Check if we are dealing with a table
lr_td = cl_abap_typedescr=>describe_by_data( data ).
if lr_td->type_kind = cl_abap_typedescr=>typekind_table.
* This information is used later...
lv_table = 'X'.
assign data to <table>.
create data ls_line like line of <table>.
assign ls_line->* to <line>.
else.
lv_table = ' '.
endif.
* Reset counters/flags
lv_off = 0.
lv_instr = ' '.
lv_level = 0.
assign lv_key to <fk>.
while lv_off < lv_len.
lv_char = json+lv_off(1).
**********************************************************************
* IN STRING
**********************************************************************
* Character is in a string delimited by double quotes
if lv_instr = 'X'.
if lv_char = '"'.
* Switch out of delimited character string
if lv_pchar ne '\'.
lv_instr = ' '.
else.
concatenate <fk> lv_char into <fk> respecting blanks.
endif.
else.
concatenate <fk> lv_char into <fk> respecting blanks.
endif.
**********************************************************************
* OUTSIDE STRING
**********************************************************************
* Character is not in a string delimited by double quotes
else.
* On opening character, shift level up
if lv_char ca '{['.
add 1 to lv_level.
endif.
* When the value is contained in a {}/[], the entire value must
* be passed to the next level of processing
if lv_level > 1.
concatenate <fk> lv_char into <fk> respecting blanks.
else.
if lv_char ca '[{'. "<- Chars ignored outside of str
elseif lv_char = ':'.
assign lv_value to <fk>.
* The key collected up to now is assigned to the data member
translate lv_key to upper case.
shift lv_key left deleting leading space.
assign component lv_key of structure data to <data>.
* End of a key/value pair (we bump up against delimiter) - pass to next level
elseif ( lv_char = ',' or lv_char = '}' ) and lv_table = space.
* Process collected value
shift lv_value left deleting leading space.
perform json_to_data using lv_value changing <data>.
* Clear key and value
clear: lv_key, lv_value.
assign lv_key to <fk>.
clear: lv_key, lv_value.
* End of a key/value pair (we bump up against delimiter) - pass to next level
* But in table mode, we pass an instance of a row of the table, and afterward
* add it to the table
elseif ( lv_char = ',' or lv_char = ']' ) and lv_table = 'X'.
* Process collected value
* Inside array in JSON, there are no keys, only list of values, the collected
* value is in lv_key
shift lv_key left deleting leading space.
perform json_to_data using lv_key changing <line>.
* On return: if dealing with table, add the record to the table
lr_ttd ?= lr_td.
if lr_ttd->table_kind = cl_abap_tabledescr=>tablekind_sorted
or lr_ttd->table_kind = cl_abap_tabledescr=>tablekind_hashed.
assign data to <sotab>.
insert <line> into table <sotab>.
else.
assign data to <sttab>.
append <line> to <sttab>.
endif.
clear <line>.
* Clear key and value
clear: lv_key, lv_value.
assign lv_key to <fk>.
clear: lv_key, lv_value.
* Switch cursor into delimited string; consecutive characters
* are then treated as part of a key or value, even if they are
* special characters
elseif lv_char = '"'.
lv_instr = 'X'.
* Other chars processed as either key or value
else.
concatenate <fk> lv_char into <fk> respecting blanks.
endif.
endif.
* On closing character, shift level down again
if lv_char ca '}]'.
subtract 1 from lv_level.
endif.
* END: Are we in string or out?
endif.
lv_pchar = lv_char.
add 1 to lv_off.
endwhile.
endform. "json_to_data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment