‎2015 Jun 07 3:13 PM
Hi...All,
I have requirement to consume RESTFUL Web service in ABAP program.
As of now i am able to consume webservice which returns single field value STATUS - PASS/FAIL.
(if we pass username and password - it will provide status return ).
But now web service is in such a way taht - it will provide Json table data as return value.
So, My concern is how to convert the JSON format table data to ABAP structure(internal Table).
Your response is highly appreciated.
Regards,
Mahesh
‎2015 Jun 07 3:16 PM
‎2015 Jun 07 3:54 PM
Hi..Ankit,
Thanks for your information.
Is Odata mandatory for Json .
Here i have small concern - is that
i have json table format data in flat file(notepad).So how can i test the same with ABAP report(Whether able to load internal table).
Suggest me please.
Regards,
Mahesh
‎2015 Jun 07 4:18 PM
No it's just an example.
You need to use transformations as shown in the example and you can convert JSON data to internal Table.
BR.
‎2015 Jun 07 4:55 PM
Hi Mahesh,
Just try the below sample code.
Input would be JSON string and output is an ABAP internal table.
FUNCTION ZFM_BPM_JSON_TO_DATA.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(JSON) TYPE STRING
*" CHANGING
*" VALUE(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.
* json_to_data( EXPORTING json = lv_value CHANGING data = <data> ).
CALL FUNCTION 'ZFM_BPM_JSON_TO_DATA'
EXPORTING
json = lv_value
CHANGING
data = <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.
CALL FUNCTION 'ZFM_BPM_JSON_TO_DATA'
EXPORTING
json = lv_key
CHANGING
data = <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.
ENDFUNCTION.
Regards,
Lokeswar Reddy Byni.
‎2015 Jul 21 10:48 PM
Hi Mahesh,
*I have a similar situation. Data in JSON format is in a array and I need to load into an internal table. Here is what i did.
*Here is my data. In this case these is only one record in array and record has one field SYS_ID.
{"RESULT":[{"SYS_ID":"6BFCC98B2B583100BBB2DCB3E4DA15F8"}]}
*Data type.
* If you have more than one field in array add those fields here.
types: begin of type_res,
sys_id type string,
end of type_res.
* data structure
DATA: str_res TYPE type_res.
* Internal Table.
data: result like TABLE OF str_res,
wa1 like LINE OF result.
FIELD-SYMBOLS: <fs1> type any.
*Data object
data: out type ref to data.
* Create object parsee
Data: parsee type ref to CL_GIS_JSON_PARSER.
create object parsee.
*Variable DAT contains the JSON data string. OUT is the data object.
CALL METHOD parsee->if_gis_parser~deserialize
EXPORTING
native_string = dat
changing
abap_data = out
.
assign out->* to <fs1>.
ASSIGN COMPONENT 1 of STRUCTURE <fs1> to FIELD-SYMBOL(<fs2>) .
* <FS2> is pointing to internal table data from JSON array.
result[] = <fs2>.
*Now you can read internal table 'result' and get the values.
read TABLE result INDEX 1 into wa1.
write:/ wa1-sys_id.
It worked for me. I hope it will work for you.
Ashok