日志存储表

ZIF_MSG 结构

MANDT        MANDT   CLNT    3   0   0   集团
GUID        APB_LPD_GUID    CHAR    32  0   0   GUID
PRONAME     FUNCNAME    CHAR    30  0   0   函数名
ERDAT       ERDAT   DATS    8   0   0   记录创建日期
ERNAM       ERNAM   CHAR    12  0   0   创建对象的人员名称
UZEIT       UZEIT   TIMS    6   0   0   时间
TYPE        WER_MSG_TYPE    CHAR    1   0   0   消息类型
MSG         UMK_Y_MESSAGE   CHAR    255 0   0   消息
PAYLOD      STRING  0   0   0   JSON
CUST_FIELD1 ZE_CUST_FIELD   CHAR    50  0   0   Custom Field
CUST_FIELD2 ZE_CUST_FIELD   CHAR    50  0   0   Custom Field
CUST_FIELD3 ZE_CUST_FIELD   CHAR    50  0   0   Custom Field

工具类

zcl_json_handler

CLASS zcl_json_handler DEFINITIONPUBLICFINALCREATE PUBLIC .PUBLIC SECTION.INTERFACES if_http_extension .TYPE-POOLS abap .CONSTANTS xnl TYPE abap_char1 VALUE %_newline.          "#EC NOTEXTCONSTANTS xcrlf TYPE abap_cr_lf VALUE %_cr_lf.          "#EC NOTEXTDATA my_service TYPE string .DATA my_url TYPE string .CLASS-METHODS abap2jsonIMPORTING!abap_data         TYPE data!name              TYPE string OPTIONAL!upcase            TYPE xfeld OPTIONAL!camelcase         TYPE xfeld OPTIONALRETURNINGVALUE(json_string) TYPE stringEXCEPTIONSerror_in_data_description .CLASS-METHODS abap2perlIMPORTING!abap_data         TYPE data!name              TYPE string OPTIONAL!upcase            TYPE xfeld OPTIONALRETURNINGVALUE(perl_string) TYPE stringEXCEPTIONSerror_in_data_description .CLASS-METHODS abap2xmlIMPORTING!abap_data        TYPE data!name             TYPE string OPTIONAL!with_xml_header  TYPE abap_bool DEFAULT abap_false!upcase           TYPE xfeld OPTIONAL!name_atr         TYPE string OPTIONALRETURNINGVALUE(xml_string) TYPE string .CLASS-METHODS abap2yamlIMPORTING!abap_data         TYPE data!name              TYPE string OPTIONAL!upcase            TYPE xfeld OPTIONAL!y_level           TYPE i DEFAULT 0!s_index           TYPE i DEFAULT 0!first_row         TYPE xfeld OPTIONAL!dont_indent       TYPE xfeld OPTIONALRETURNINGVALUE(yaml_string) TYPE stringEXCEPTIONSerror_in_data_description .CLASS-METHODS build_paramsIMPORTING!function_name TYPE rs38l_fnamEXPORTING!paramtab      TYPE abap_func_parmbind_tab!exceptab      TYPE abap_func_excpbind_tab!params        TYPE anyEXCEPTIONSinvalid_functionunsupported_param_type .TYPE-POOLS js .CLASS-METHODS json2abapIMPORTING!json_string    TYPE string OPTIONAL!var_name       TYPE string OPTIONAL!property_path  TYPE string DEFAULT 'json_obj'EXPORTING!property_table TYPE js_property_tabCHANGING!js_object      TYPE REF TO cl_java_script!abap_data      TYPE any OPTIONALRAISINGzcx_json .CLASS-METHODS json_deserializeIMPORTING!json     TYPE stringCHANGING!paramtab TYPE abap_func_parmbind_tabEXCEPTIONSzcx_json .METHODS notesRETURNINGVALUE(text) TYPE string .CLASS-METHODS serialize_jsonIMPORTING!paramtab  TYPE abap_func_parmbind_tab!params    TYPE any OPTIONAL!exceptab  TYPE abap_func_excpbind_tab OPTIONAL!show_impp TYPE abap_bool OPTIONAL!jsonp     TYPE string OPTIONAL!lowercase TYPE abap_bool DEFAULT abap_false!camelcase TYPE abap_bool DEFAULT abap_falseEXPORTING!o_string  TYPE string .CLASS-METHODS serialize_perlIMPORTING!paramtab    TYPE abap_func_parmbind_tab!params      TYPE any OPTIONAL!exceptab    TYPE abap_func_excpbind_tab OPTIONAL!show_impp   TYPE abap_bool OPTIONAL!jsonp       TYPE string OPTIONAL!lowercase   TYPE abap_bool DEFAULT abap_false!funcname    TYPE rs38l_fnamEXPORTING!perl_string TYPE string .CLASS-METHODS serialize_xmlIMPORTING!paramtab  TYPE abap_func_parmbind_tab!params    TYPE any OPTIONAL!exceptab  TYPE abap_func_excpbind_tab OPTIONAL!show_impp TYPE abap_bool OPTIONAL!jsonp     TYPE string OPTIONAL!funcname  TYPE rs38l_fnam!lowercase TYPE abap_bool DEFAULT abap_false!format    TYPE stringEXPORTING!o_string  TYPE string .CLASS-METHODS serialize_yamlIMPORTING!paramtab    TYPE abap_func_parmbind_tab!params      TYPE any!exceptab    TYPE abap_func_excpbind_tab!show_impp   TYPE abap_bool!jsonp       TYPE string!lowercase   TYPE abap_bool DEFAULT abap_falseEXPORTING!yaml_string TYPE string .CLASS-METHODS deserialize_idIMPORTING!json     TYPE stringCHANGING!paramtab TYPE abap_func_parmbind_tabRAISINGzcx_json .CLASS-METHODS serialize_idIMPORTING!paramtab  TYPE abap_func_parmbind_tab!params    TYPE any OPTIONAL!exceptab  TYPE abap_func_excpbind_tab OPTIONAL!show_impp TYPE abap_bool OPTIONAL!jsonp     TYPE string OPTIONAL!lowercase TYPE abap_bool DEFAULT abap_false!format    TYPE string DEFAULT 'JSON'!funcname  TYPE rs38l_fnam OPTIONAL!camelcase TYPE abap_bool DEFAULT abap_falseEXPORTING!o_string  TYPE stringRAISINGzcx_json .CLASS-METHODS convert_json_datetime_to_abapIMPORTING!iv_timestamp TYPE stringEXPORTING!ev_date      TYPE sydate!ev_time      TYPE syuzeit!ev_msec      TYPE num03 .PROTECTED SECTION.PRIVATE SECTION.
ENDCLASS.CLASS zcl_json_handler IMPLEMENTATION.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON_HANDLER=>ABAP2JSON
* +-------------------------------------------------------------------------------------------------+
* | [--->] ABAP_DATA                      TYPE        DATA
* | [--->] NAME                           TYPE        STRING(optional)
* | [--->] UPCASE                         TYPE        XFELD(optional)
* | [--->] CAMELCASE                      TYPE        XFELD(optional)
* | [<-()] JSON_STRING                    TYPE        STRING
* | [EXC!] ERROR_IN_DATA_DESCRIPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD abap2json.
*/**********************************************/*
*/ This method takes any ABAP data variable and /*
*/ returns a string representing its value in   /*
*/ JSON format.                                 /*
*/ ABAP references are always de-referenced and /*
*/ treated as normal variables.                 /*
*/**********************************************/*TYPE-POOLS: abap.CONSTANTS:c_comma TYPE c VALUE ',',c_colon TYPE c VALUE ':',c_quote TYPE c VALUE '"'.DATA:dont_quote      TYPE xfeld,json_fragments  TYPE TABLE OF string,rec_json_string TYPE string,l_type          TYPE c,s_type          TYPE c,l_comps         TYPE i,l_lines         TYPE i,l_index         TYPE i,l_value         TYPE string,l_name          TYPE string,l_strudescr     TYPE REF TO cl_abap_structdescr.FIELD-SYMBOLS:<abap_data> TYPE any,<itab>      TYPE ANY TABLE,<stru>      TYPE ANY TABLE,<comp>      TYPE any,<abapcomp>  TYPE abap_compdescr.DEFINE get_scalar_value." &1 : assigned var" &2 : abap data" &3 : abap type&1 = &2.
****************************************************
* Adapt some basic ABAP types (pending inclusion of all basic abap types?)
* Feel free to customize this for your needsCASE &3.
*       1. ABAP numeric typesWHEN 'I'. " IntegerCONDENSE &1.IF sign( &1 ) < 0.SHIFT &1 BY 1 PLACES RIGHT CIRCULAR.ENDIF.dont_quote = 'X'.WHEN 'F'. " FloatCONDENSE &1.dont_quote = 'X'.WHEN 'P'. " Packed number (used in quantities or currency, for example)CONDENSE &1.IF sign( &1 ) < 0.SHIFT &1 BY 1 PLACES RIGHT CIRCULAR.ENDIF.dont_quote = 'X'.WHEN 'X'. " HexadecimalCONDENSE &1.CONCATENATE '0x' &1 INTO &1.
*        dont_quote = 'X'.
*        "Quote it, as JSON doesn't support Hex or Octal as native types.*       2. ABAP char typesWHEN 'D'. " Date typeCONCATENATE &1(4) '-' &1+4(2) '-' &1+6(2) INTO &1.WHEN 'T'. " Time representationCONCATENATE &1(2) ':' &1+2(2) ':' &1+4(2) INTO &1.WHEN 'N'. " Numeric text field
*           condense &1.WHEN 'C' OR 'g'. " Char sequences and Strings
* Put safe charsREPLACE ALL OCCURRENCES OF '\' IN &1 WITH '\\' .REPLACE ALL OCCURRENCES OF '"' IN &1 WITH '\"' .REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>cr_lf IN &1 WITH '\r\n' .REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>newline IN &1 WITH '\n' .REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>horizontal_tab IN &1 WITH '\t' .REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>backspace IN &1 WITH '\b' .REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>form_feed IN &1 WITH '\f' .WHEN 'y'.  " XSTRING
* Put the XSTRING in Base64&1 = cl_http_utility=>encode_x_base64( &2 ).WHEN OTHERS.
* Don't hesitate to add and modify scalar abap types to suit your taste.ENDCASE.
** End of scalar data preparing.* Enclose value in quotes (or not)IF dont_quote NE 'X'.CONCATENATE c_quote &1 c_quote INTO &1.ENDIF.CLEAR dont_quote.end-of-definition.***************************************************
*  Prepare field names, JSON does quote names!!   *
*  You must be strict in what you produce.        *
***************************************************IF name IS NOT INITIAL.CONCATENATE c_quote name c_quote c_colon INTO rec_json_string.APPEND rec_json_string TO json_fragments.CLEAR rec_json_string.ENDIF.**
* Get ABAP data typeDESCRIBE FIELD abap_data TYPE l_type COMPONENTS l_comps.***************************************************
*  Get rid of data references
***************************************************IF l_type EQ cl_abap_typedescr=>typekind_dref.ASSIGN abap_data->* TO <abap_data>.IF sy-subrc NE 0.APPEND '{}' TO json_fragments.CONCATENATE LINES OF json_fragments INTO json_string.EXIT.ENDIF.ELSE.ASSIGN abap_data TO <abap_data>.ENDIF.* Get ABAP data type again and startDESCRIBE FIELD <abap_data> TYPE l_type COMPONENTS l_comps.***************************************************
*  Tables
***************************************************IF l_type EQ cl_abap_typedescr=>typekind_table.
* '[' JSON table opening bracketAPPEND '[' TO json_fragments.ASSIGN <abap_data> TO <itab>.l_lines = lines( <itab> ).LOOP AT <itab> ASSIGNING <comp>.ADD 1 TO l_index.
*> Recursive call for each table row:rec_json_string = abap2json( abap_data = <comp> upcase = upcase camelcase = camelcase ).APPEND rec_json_string TO json_fragments.CLEAR rec_json_string.IF l_index < l_lines.APPEND c_comma TO json_fragments.ENDIF.ENDLOOP.APPEND ']' TO json_fragments.
* ']' JSON table closing bracket***************************************************
*  Structures
***************************************************ELSE.IF l_comps IS NOT INITIAL.
* '{' JSON object opening curly braceAPPEND '{' TO json_fragments.l_strudescr ?= cl_abap_typedescr=>describe_by_data( <abap_data> ).LOOP AT l_strudescr->components ASSIGNING <abapcomp>.l_index = sy-tabix .ASSIGN COMPONENT <abapcomp>-name OF STRUCTURE <abap_data> TO <comp>.l_name = <abapcomp>-name.
** ABAP names are usually in caps, set upcase to avoid the conversion to lower case.IF upcase NE 'X'." translate l_name to lower case.l_name = to_lower( l_name ).ENDIF.IF camelcase EQ 'X'.DATA:lv_name1 TYPE char50.lv_name1 = l_name.lv_name1 = to_mixed( val = l_name  case = 'A' ).l_name = to_lower( lv_name1 ).ENDIF.DESCRIBE FIELD <comp> TYPE s_type.IF s_type EQ cl_abap_typedescr=>typekind_table OR s_type EQ cl_abap_typedescr=>typekind_dref ORs_type EQ cl_abap_typedescr=>typekind_struct1 OR s_type EQ cl_abap_typedescr=>typekind_struct2.
*> Recursive call for non-scalars:rec_json_string = abap2json( abap_data = <comp> name = l_name upcase = upcase camelcase = camelcase ).ELSE.IF s_type EQ cl_abap_typedescr=>typekind_oref OR s_type EQ cl_abap_typedescr=>typekind_iref.rec_json_string = '"REF UNSUPPORTED"'.ELSE.get_scalar_value rec_json_string <comp> s_type.ENDIF.CONCATENATE c_quote l_name c_quote c_colon rec_json_string INTO rec_json_string.ENDIF.APPEND rec_json_string TO json_fragments.CLEAR rec_json_string. CLEAR l_name.IF l_index < l_comps.APPEND c_comma TO json_fragments.ENDIF.ENDLOOP.APPEND '}' TO json_fragments.
* '}' JSON object closing curly brace****************************************************
*                  - Scalars -                     *
****************************************************ELSE.get_scalar_value l_value <abap_data> l_type.APPEND l_value TO json_fragments.ENDIF.
* End of structure/scalar IF block.
***********************************ENDIF.
* End of main IF block.
*********************** Use a loop in older releases that don't support concatenate lines.CONCATENATE LINES OF json_fragments INTO json_string.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON_HANDLER=>ABAP2PERL
* +-------------------------------------------------------------------------------------------------+
* | [--->] ABAP_DATA                      TYPE        DATA
* | [--->] NAME                           TYPE        STRING(optional)
* | [--->] UPCASE                         TYPE        XFELD(optional)
* | [<-()] PERL_STRING                    TYPE        STRING
* | [EXC!] ERROR_IN_DATA_DESCRIPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD abap2perl.
*/**********************************************/*
*/ This method takes any ABAP data variable and /*
*/ returns a string representing its value in   /*
*/ Perl Data::Dumper format, ready to be evaled /*
*/ in a Perl program.                           /*
*/**********************************************/*TYPE-POOLS: abap.CONSTANTS:c_comma TYPE c VALUE ',',c_colon TYPE c VALUE ':',c_quote TYPE c VALUE ''''.DATA:perl_hash_assign TYPE string,dont_quote       TYPE xfeld,perl_fragments   TYPE TABLE OF string,rec_perl_string  TYPE string,l_type           TYPE c,s_type           TYPE c,l_comps          TYPE i,l_lines          TYPE i,l_index          TYPE i,l_value          TYPE string,l_name           TYPE string,l_typedescr      TYPE REF TO cl_abap_structdescr.FIELD-SYMBOLS:<abap_data> TYPE any,<itab>      TYPE ANY TABLE,<stru>      TYPE ANY TABLE,<comp>      TYPE any,<abapcomp>  TYPE abap_compdescr.CONCATENATE space '=>' space INTO perl_hash_assign RESPECTING BLANKS.DEFINE get_scalar_value." &1 : assigned var" &2 : abap data" &3 : abap type&1 = &2.
****************************************************
* Adapt some basic ABAP types (pending inclusion of all basic abap types?)
* Feel free to customize this for your needsCASE &3.
*       1. ABAP numeric typesWHEN 'I'. " IntegerCONDENSE &1.IF sign( &1 ) < 0.SHIFT &1 BY 1 PLACES RIGHT CIRCULAR.ENDIF.dont_quote = 'X'.WHEN 'F'. " FloatCONDENSE &1.dont_quote = 'X'.WHEN 'P'. " Packed number (used in quantities, for example)CONDENSE &1.IF sign( &1 ) < 0.SHIFT &1 BY 1 PLACES RIGHT CIRCULAR.ENDIF.dont_quote = 'X'.WHEN 'X'. " HexadecimalCONDENSE &1.CONCATENATE '0x' &1 INTO &1.dont_quote = 'X'.*       2. ABAP char typesWHEN 'D'. " Date typeCONCATENATE &1(4) '-' &1+4(2) '-' &1+6(2) INTO &1.WHEN 'T'. " Time representationCONCATENATE &1(2) ':' &1+2(2) ':' &1+4(2) INTO &1.WHEN 'N'. " Numeric text field
*           condense &1.WHEN 'C' OR 'g'. " Char sequences and Strings
* Put safe charsREPLACE ALL OCCURRENCES OF '''' IN &1 WITH '\''' .WHEN 'y'.  " XSTRING
* Put the XSTRING in Base64&1 = cl_http_utility=>encode_x_base64( &2 ).WHEN OTHERS.
* Don't hesitate to add and modify abap types to suit your taste.ENDCASE.
** End of scalar data preparing.* Enclose value in quotes (or not)IF dont_quote NE 'X'.CONCATENATE c_quote &1 c_quote INTO &1.ENDIF.CLEAR dont_quote.end-of-definition.***************************************************
*  Prepare field names, we use single quotes.     *
*  You must be strict in what you produce.        *
***************************************************IF name IS NOT INITIAL.CONCATENATE c_quote name c_quote perl_hash_assign INTO rec_perl_string RESPECTING BLANKS.APPEND rec_perl_string TO perl_fragments.CLEAR rec_perl_string.ENDIF.**
* Get ABAP data typeDESCRIBE FIELD abap_data TYPE l_type COMPONENTS l_comps.***************************************************
*  Get rid of data references
***************************************************IF l_type EQ cl_abap_typedescr=>typekind_dref.ASSIGN abap_data->* TO <abap_data>.IF sy-subrc NE 0.APPEND '{}' TO perl_fragments.CONCATENATE LINES OF perl_fragments INTO perl_string.EXIT.ENDIF.ELSE.ASSIGN abap_data TO <abap_data>.ENDIF.* Get ABAP data type again and startDESCRIBE FIELD <abap_data> TYPE l_type COMPONENTS l_comps.***************************************************
*  Tables
***************************************************IF l_type EQ cl_abap_typedescr=>typekind_table.
* '[' Table opening bracketAPPEND '[' TO perl_fragments.ASSIGN <abap_data> TO <itab>.l_lines = lines( <itab> ).LOOP AT <itab> ASSIGNING <comp>.ADD 1 TO l_index.
*> Recursive call hererec_perl_string = abap2perl( abap_data = <comp> upcase = upcase ).APPEND rec_perl_string TO perl_fragments.CLEAR rec_perl_string.IF l_index < l_lines.APPEND c_comma TO perl_fragments.ENDIF.ENDLOOP.APPEND ']' TO perl_fragments.
* ']' Table closing bracket***************************************************
*  Structures
***************************************************ELSE .IF l_comps IS NOT INITIAL.
* '{' Object opening curly braceAPPEND '{' TO perl_fragments .l_typedescr ?= cl_abap_typedescr=>describe_by_data( <abap_data> ) .LOOP AT l_typedescr->components ASSIGNING <abapcomp> .l_index = sy-tabix .ASSIGN COMPONENT <abapcomp>-name OF STRUCTURE <abap_data> TO <comp>.l_name = <abapcomp>-name.
** ABAP names are usually in caps, set upcase to avoid the conversion to lower case.IF upcase NE 'X'.TRANSLATE l_name TO LOWER CASE.ENDIF.DESCRIBE FIELD <comp> TYPE s_type.IF s_type EQ cl_abap_typedescr=>typekind_table OR s_type EQ cl_abap_typedescr=>typekind_dref ORs_type EQ cl_abap_typedescr=>typekind_struct1 OR s_type EQ cl_abap_typedescr=>typekind_struct2.
*> Recursive call for non-scalars:rec_perl_string = abap2perl( abap_data = <comp> name = l_name upcase = upcase ).ELSE.IF s_type EQ cl_abap_typedescr=>typekind_oref OR s_type EQ cl_abap_typedescr=>typekind_iref.rec_perl_string = '"REF UNSUPPORTED"'.ELSE.get_scalar_value rec_perl_string <comp> s_type.ENDIF.CONCATENATE c_quote l_name c_quote perl_hash_assign rec_perl_string INTO rec_perl_string.ENDIF.APPEND rec_perl_string TO perl_fragments.CLEAR rec_perl_string.IF l_index < l_comps.APPEND c_comma TO perl_fragments.ENDIF.ENDLOOP.APPEND '}' TO perl_fragments.
* '}' Object closing curly brace****************************************************
*                  - Scalars -                     *
****************************************************ELSE.get_scalar_value l_value <abap_data> l_type.APPEND l_value TO perl_fragments.ENDIF.
* End of structure/scalar IF block.
***********************************ENDIF.
* End of main IF block.
*********************** Use a loop in older releases that don't support concatenate lines.CONCATENATE LINES OF perl_fragments INTO perl_string.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON_HANDLER=>ABAP2XML
* +-------------------------------------------------------------------------------------------------+
* | [--->] ABAP_DATA                      TYPE        DATA
* | [--->] NAME                           TYPE        STRING(optional)
* | [--->] WITH_XML_HEADER                TYPE        ABAP_BOOL (default =ABAP_FALSE)
* | [--->] UPCASE                         TYPE        XFELD(optional)
* | [--->] NAME_ATR                       TYPE        STRING(optional)
* | [<-()] XML_STRING                     TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD abap2xml.
*
*/ Look at method serialize_id for a new way of doing XML.TYPE-POOLS: abap.CONSTANTS:xml_head TYPE string VALUE '<?xml version="1.0" encoding="utf-8"?>',item_atr TYPE string VALUE 'idx="#"'.DATA:xml_fragments  TYPE TABLE OF string,rec_xml_string TYPE string,l_type         TYPE c,s_type         TYPE c,l_comps        TYPE i,l_value        TYPE string,t_string       TYPE string,l_item_atr     TYPE string,l_item_str     TYPE string,l_name         TYPE string,l_idx          TYPE string,l_typedescr    TYPE REF TO cl_abap_structdescr,l_linedescr    TYPE REF TO cl_abap_datadescr,l_tabledescr   TYPE REF TO cl_abap_tabledescr.FIELD-SYMBOLS:<abap_data> TYPE any,<itab>      TYPE ANY TABLE,<stru>      TYPE ANY TABLE,<comp>      TYPE any,<abapcomp>  TYPE abap_compdescr.DEFINE get_scalar_value." &1 : assigned var" &2 : abap data" &3 : abap type&1 = &2.
****************************************************
* Adapt some basic ABAP types (pending inclusion of all basic abap types?)
* Feel free to customize this for your needsCASE &3.
*       1. ABAP numeric typesWHEN 'I'. " IntegerCONDENSE &1.IF sign( &1 ) < 0.SHIFT &1 BY 1 PLACES RIGHT CIRCULAR.ENDIF.WHEN 'F'. " FloatCONDENSE &1.WHEN 'P'. " Packed number (used in quantities, for example)CONDENSE &1.IF sign( &1 ) < 0.SHIFT &1 BY 1 PLACES RIGHT CIRCULAR.ENDIF.WHEN 'X'. " HexadecimalCONDENSE &1.CONCATENATE '0x' &1 INTO &1.*       2. ABAP char typesWHEN 'D'. " Date typeCONCATENATE &1(4) '-' &1+4(2) '-' &1+6(2) INTO &1.WHEN 'T'. " Time representationCONCATENATE &1(2) ':' &1+2(2) ':' &1+4(2) INTO &1.WHEN 'N'. " Numeric text field
*           condense &1.WHEN 'C' OR 'g'. " Char sequences and Strings
* Put safe charst_string = &2.&1 = cl_http_utility=>escape_html( t_string ).WHEN 'y'.  " XSTRING
* Put the XSTRING in Base64&1 = cl_http_utility=>encode_x_base64( &2 ).WHEN OTHERS.
* Don't hesitate to add and modify abap types to suit your taste.ENDCASE.
** End of scalar data preparing.end-of-definition.*******************************
* Put XML header if requested *
*******************************IF with_xml_header EQ abap_true.APPEND xml_head TO xml_fragments.ENDIF.***************************************************
*  Open XML tag                                   *
*  <          >                                   *
***************************************************IF name IS NOT INITIAL.l_name = name.IF name_atr IS NOT INITIAL.CONCATENATE name name_atr INTO l_name SEPARATED BY space.ENDIF.CONCATENATE '<' l_name '>' INTO rec_xml_string.APPEND rec_xml_string TO xml_fragments.CLEAR rec_xml_string.ENDIF.**
* Get ABAP data typeDESCRIBE FIELD abap_data TYPE l_type COMPONENTS l_comps .***************************************************
*  Get rid of data references
***************************************************IF l_type EQ cl_abap_typedescr=>typekind_dref.ASSIGN abap_data->* TO <abap_data>.IF sy-subrc NE 0.IF name IS NOT INITIAL.CONCATENATE '<' name '/>' INTO xml_string.ELSE.CLEAR xml_string.ENDIF.EXIT.ENDIF.ELSE.ASSIGN abap_data TO <abap_data>.ENDIF.* Get ABAP data type again and startDESCRIBE FIELD <abap_data> TYPE l_type COMPONENTS l_comps.***************************************************
*  Tables
***************************************************IF l_type EQ cl_abap_typedescr=>typekind_table.l_tabledescr ?= cl_abap_typedescr=>describe_by_data( <abap_data> ).l_linedescr = l_tabledescr->get_table_line_type( ).l_item_str = l_linedescr->get_relative_name( ).ASSIGN <abap_data> TO <itab>.LOOP AT <itab> ASSIGNING <comp>.l_idx = sy-tabix.CONDENSE l_idx.l_item_atr = item_atr.REPLACE '#' IN l_item_atr WITH l_idx.IF upcase NE 'X'.TRANSLATE l_item_str TO LOWER CASE.ENDIF.
*> Recursive call for line items here:rec_xml_string = abap2xml( abap_data = <comp> upcase = upcase name = l_item_str name_atr = l_item_atr ).APPEND rec_xml_string TO xml_fragments.CLEAR rec_xml_string.ENDLOOP.***************************************************
*  Structures
***************************************************ELSE .IF l_comps IS NOT INITIAL.l_typedescr ?= cl_abap_typedescr=>describe_by_data( <abap_data> ).LOOP AT l_typedescr->components ASSIGNING <abapcomp> .ASSIGN COMPONENT <abapcomp>-name OF STRUCTURE <abap_data> TO <comp>.l_name = <abapcomp>-name. " l_value justs holds the name here.
** ABAP names are usually in caps, set upcase to avoid the conversion to lower case.IF upcase NE 'X'.TRANSLATE l_name TO LOWER CASE.ENDIF.DESCRIBE FIELD <comp> TYPE s_type.IF s_type EQ cl_abap_typedescr=>typekind_table OR s_type EQ cl_abap_typedescr=>typekind_dref ORs_type EQ cl_abap_typedescr=>typekind_struct1 OR s_type EQ cl_abap_typedescr=>typekind_struct2.
*> Recursive call for non-scalars:rec_xml_string = abap2xml( abap_data = <comp> name = l_name upcase = upcase ).ELSE.IF s_type EQ cl_abap_typedescr=>typekind_oref OR s_type EQ cl_abap_typedescr=>typekind_iref.rec_xml_string = 'REF UNSUPPORTED'.ELSE.get_scalar_value rec_xml_string <comp> s_type.ENDIF.CONCATENATE '<' l_name '>' rec_xml_string '</' l_name '>' INTO rec_xml_string.ENDIF.APPEND rec_xml_string TO xml_fragments.CLEAR rec_xml_string.ENDLOOP.****************************************************
*                  - Scalars -                     *
****************************************************ELSE.get_scalar_value l_value <abap_data> l_type.APPEND l_value TO xml_fragments.ENDIF.
* End of structure/scalar IF block.
***********************************ENDIF.
* End of main IF block.
***************************************
* Close XML tag *
*****************IF name IS NOT INITIAL.CONCATENATE '</' name '>' INTO rec_xml_string.APPEND rec_xml_string TO xml_fragments.CLEAR rec_xml_string.ENDIF.* Use a loop in older releases that don't support concatenate lines.CONCATENATE LINES OF xml_fragments INTO xml_string.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON_HANDLER=>ABAP2YAML
* +-------------------------------------------------------------------------------------------------+
* | [--->] ABAP_DATA                      TYPE        DATA
* | [--->] NAME                           TYPE        STRING(optional)
* | [--->] UPCASE                         TYPE        XFELD(optional)
* | [--->] Y_LEVEL                        TYPE        I (default =0)
* | [--->] S_INDEX                        TYPE        I (default =0)
* | [--->] FIRST_ROW                      TYPE        XFELD(optional)
* | [--->] DONT_INDENT                    TYPE        XFELD(optional)
* | [<-()] YAML_STRING                    TYPE        STRING
* | [EXC!] ERROR_IN_DATA_DESCRIPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD abap2yaml.
*********************
* ABAP goes to YAML *
*********************TYPE-POOLS: abap.CONSTANTS:c_comma    TYPE c VALUE ',',c_space    TYPE c VALUE ' ',c_colon    TYPE c VALUE ':',c_quote    TYPE c VALUE '"',c_squot    TYPE c VALUE '''',c_colo2(2) TYPE c VALUE ': ',c_indt2    TYPE i VALUE 2,c_hyph     TYPE c VALUE '-'.DATA:ly_level        TYPE i,l_dont_indent   TYPE xfeld,dec_level       TYPE i VALUE 0,dont_quote      TYPE xfeld,yaml_fragments  TYPE TABLE OF string,rec_yaml_string TYPE string,l_type          TYPE c,l_comps         TYPE i,l_lines         TYPE i,l_index         TYPE i,l_value         TYPE string,l_name          TYPE string.FIELD-SYMBOLS:<abap_data> TYPE any,<itab>      TYPE ANY TABLE,<stru>      TYPE ANY TABLE,<comp>      TYPE any.DATA l_typedescr TYPE REF TO cl_abap_structdescr .FIELD-SYMBOLS <abapcomp> TYPE abap_compdescr .ly_level = y_level.**
* Get ABAP data typeDESCRIBE FIELD abap_data TYPE l_type COMPONENTS l_comps .***************************************************
*  First of all, get rid of data references
***************************************************IF l_type EQ cl_abap_typedescr=>typekind_dref.ASSIGN abap_data->* TO <abap_data>.IF sy-subrc NE 0.yaml_string = space. " pasamos de poner nada si falla...EXIT.ENDIF.ELSE.ASSIGN abap_data TO <abap_data>.ENDIF.* Get ABAP data type again and startDESCRIBE FIELD <abap_data> TYPE l_type COMPONENTS l_comps.***************************************************
*  Prepare field names, YAML does not quote names *
***************************************************
* Put hyphens...IF name IS INITIAL AND y_level GT 0.CONCATENATE c_hyph space INTO rec_yaml_string RESPECTING BLANKS.l_dont_indent = 'X'.ENDIF.IF name IS NOT INITIAL.CONCATENATE name c_colon c_space INTO rec_yaml_string RESPECTING BLANKS.ENDIF.* do indentIF dont_indent NE 'X'.DO  ly_level  TIMES.SHIFT rec_yaml_string RIGHT BY c_indt2 PLACES.ENDDO.ENDIF.APPEND rec_yaml_string TO yaml_fragments.CLEAR rec_yaml_string.***************************************************
*  Tables
***************************************************IF l_type EQ cl_abap_typedescr=>typekind_table.ASSIGN <abap_data> TO <itab>.l_lines = lines( <itab> ).CLEAR l_index.IF l_lines EQ 0.MOVE '[]' TO rec_yaml_string.APPEND rec_yaml_string TO yaml_fragments.CLEAR rec_yaml_string.APPEND xnl TO yaml_fragments.ELSE.IF name IS NOT INITIAL.APPEND xnl TO yaml_fragments.ENDIF.ADD 1 TO ly_level.LOOP AT <itab> ASSIGNING <comp>.ADD 1 TO l_index.
*> Recursive call hererec_yaml_string = abap2yaml( abap_data = <comp> upcase = upcase y_level = ly_level s_index = l_index ).APPEND rec_yaml_string TO yaml_fragments.CLEAR rec_yaml_string.ENDLOOP.ENDIF.
* YAML table ends *
**********************************************************************
*  Structures
***************************************************ELSE .IF l_comps IS NOT INITIAL.IF name IS NOT INITIAL.APPEND xnl TO yaml_fragments.ENDIF.ADD 1 TO ly_level.
* Loop for structure elementsl_typedescr ?= cl_abap_typedescr=>describe_by_data( <abap_data> ) .CLEAR l_index.LOOP AT l_typedescr->components ASSIGNING <abapcomp>.ADD 1 TO l_index.ASSIGN COMPONENT <abapcomp>-name OF STRUCTURE <abap_data> TO <comp>.l_name = <abapcomp>-name.
** ABAP names are usually in caps, set upcase to avoid the conversion to lower case.IF upcase NE 'X'.TRANSLATE l_name TO LOWER CASE.ENDIF.
*> Recursive call hererec_yaml_string = abap2yaml( abap_data = <comp> name = l_name upcase = upcase y_level = ly_level s_index = l_index dont_indent = l_dont_indent ).CLEAR l_dont_indent. " it is only used onceAPPEND rec_yaml_string TO yaml_fragments.CLEAR rec_yaml_string.ENDLOOP.* YAML structure ends *
**************************************************************************
*  Scalars and others...
***************************************************ELSE.IF l_type EQ cl_abap_typedescr=>typekind_oref OR l_type EQ cl_abap_typedescr=>typekind_iref.l_value = 'REF UNSUPPORTED'.ELSE.l_value = <abap_data>.ENDIF.* Adapt some basic ABAP types (pending inclusion of all basic abap types)
* Feel free to customize this for your needsCASE l_type.
*       1. ABAP numeric typesWHEN 'I'. " IntegerCONDENSE l_value.IF sign( l_value ) < 0.SHIFT l_value BY 1 PLACES RIGHT CIRCULAR.ENDIF.dont_quote = 'X'.WHEN 'F'. " FloatCONDENSE l_value.dont_quote = 'X'.WHEN 'P'. " Packed number (used in quantities, for example)CONDENSE l_value.IF sign( l_value ) < 0.SHIFT l_value BY 1 PLACES RIGHT CIRCULAR.ENDIF.dont_quote = 'X'.WHEN 'X'. " HexadecimalCONDENSE l_value.CONCATENATE '0x' l_value INTO l_value.dont_quote = 'X'.*       2. ABAP char typesWHEN 'D'. " Date typeCONCATENATE l_value(4) '-' l_value+4(2) '-' l_value+6(2) INTO l_value.WHEN 'T'. " Time representationCONCATENATE l_value(2) ':' l_value+2(2) ':' l_value+4(2) INTO l_value.WHEN 'N'. " Numeric text field
*           condense l_value.WHEN 'C' OR 'g'. " Chars and Strings
* Put safe charsREPLACE ALL OCCURRENCES OF '\' IN l_value WITH '\\' .REPLACE ALL OCCURRENCES OF '"' IN l_value WITH '\"' .REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>cr_lf IN l_value WITH '\r\n' .REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>newline IN l_value WITH '\n' .REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>horizontal_tab IN l_value WITH '\t' .REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>backspace IN l_value WITH '\b' .REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>form_feed IN l_value WITH '\f' .WHEN 'y'.  " XSTRING
* Put the XSTRING in Base64
*          l_value = cl_http_utility=>ENCODE_X_BASE64( <abap_data> ).l_value = 'XSTRING not supported in YAML yet!'.WHEN OTHERS.
* Don't hesitate to add and modify abap types to suit your taste.ENDCASE.* We use YAML scalars double quotedIF dont_quote NE 'X'.CONCATENATE c_quote l_value c_quote INTO l_value.ELSE.CLEAR dont_quote.ENDIF.APPEND l_value TO yaml_fragments.APPEND xnl TO yaml_fragments.ENDIF. " is structure or scalarENDIF. " main typekind sentence* Use a loop in older releases that don't support concatenate lines.CONCATENATE LINES OF yaml_fragments INTO yaml_string RESPECTING BLANKS.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON_HANDLER=>BUILD_PARAMS
* +-------------------------------------------------------------------------------------------------+
* | [--->] FUNCTION_NAME                  TYPE        RS38L_FNAM
* | [<---] PARAMTAB                       TYPE        ABAP_FUNC_PARMBIND_TAB
* | [<---] EXCEPTAB                       TYPE        ABAP_FUNC_EXCPBIND_TAB
* | [<---] PARAMS                         TYPE        ANY
* | [EXC!] INVALID_FUNCTION
* | [EXC!] UNSUPPORTED_PARAM_TYPE
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD build_params.TYPE-POOLS: abap.DATA defval TYPE rs38l_defo.DATA dataname TYPE string.DATA waref TYPE REF TO data.FIELD-SYMBOLS:<wa>   TYPE any,<temp> TYPE any.DATA len TYPE i.DATA excnt TYPE i VALUE 1.DATA paramline  TYPE LINE  OF abap_func_parmbind_tab.DATA exceptline TYPE LINE  OF abap_func_excpbind_tab.DATA t_params_p TYPE TABLE OF rfc_fint_p.DATA params_p   TYPE rfc_fint_p.DEFINE remove_enclosing_quotes." Remove enclosing single quotesIF &2 GT 1.SUBTRACT 1 FROM &2.IF &1+&2 EQ ''''.&1+&2 = space.ENDIF.IF &1(1) EQ ''''.SHIFT &1 LEFT.ENDIF.&2 = strlen( &1 ).ENDIF.end-of-definition.* do we have the rfc name?CALL FUNCTION 'RFC_GET_FUNCTION_INTERFACE_P'EXPORTINGfuncname      = function_namelanguage      = 'E'       "'D'  "sy-languTABLESparams_p      = t_params_pEXCEPTIONSfu_not_found  = 1nametab_fault = 2OTHERS        = 3.IF sy-subrc <> 0.RAISE invalid_function.ENDIF.* Build params tableLOOP AT t_params_p INTO params_p.UNASSIGN <wa>.UNASSIGN <temp>.CLEAR paramline.CASE params_p-paramclass.WHEN 'I' OR 'E' OR 'C'.paramline-name = params_p-parameter.IF params_p-paramclass = 'E'.paramline-kind = abap_func_importing.ELSEIF params_p-paramclass = 'I'.paramline-kind = abap_func_exporting.ELSE.paramline-kind = abap_func_changing.ENDIF.IF params_p-fieldname IS INITIAL.dataname = params_p-tabname.ELSE.CONCATENATE params_p-tabname params_p-fieldname INTOdataname SEPARATED BY '-'.ENDIF.* Assign default valuesdefval = params_p-default.IF dataname IS INITIAL.dataname = 'STRING'.  " use a STRING for this cases (see CONVERT_DATE_TO_EXTERNAL).ENDIF.CREATE DATA waref TYPE (dataname).ASSIGN waref->* TO <wa>.len = strlen( defval ).remove_enclosing_quotes defval len.IF defval = 'SPACE'.<wa> = space.ELSEIF len > 3 AND defval+0(3) = 'SY-'.ASSIGN (defval) TO <temp>.<wa> = <temp>.UNASSIGN <temp>.ELSE.IF defval IS NOT INITIAL.<wa> = defval.ENDIF.ENDIF.UNASSIGN <wa>.paramline-value = waref.INSERT paramline INTO TABLE paramtab.WHEN 'T'.paramline-name = params_p-parameter.paramline-kind = abap_func_tables.IF params_p-exid EQ 'h'.CREATE DATA waref TYPE (params_p-tabname).ELSE.CREATE DATA waref TYPE STANDARD TABLE OF (params_p-tabname).ENDIF.paramline-value = waref.INSERT paramline INTO TABLE paramtab.WHEN 'X'.exceptline-name = params_p-parameter.exceptline-value = excnt.DATA messg TYPE REF TO data.CREATE DATA messg TYPE string.ASSIGN messg->* TO <temp>.<temp> = params_p-paramtext.exceptline-message = messg.INSERT exceptline INTO TABLE exceptab.ADD 1 TO excnt.WHEN OTHERS.RAISE unsupported_param_type.ENDCASE.ENDLOOP.* add in the catch all exceptionexceptline-name = 'OTHERS'.exceptline-value = excnt.INSERT exceptline INTO TABLE exceptab.* returnparams = t_params_p.*********************************
******* Remaining from 2006 *****
******* end of build_params *****
*********************************ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON_HANDLER=>CONVERT_JSON_DATETIME_TO_ABAP
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_TIMESTAMP                   TYPE        STRING
* | [<---] EV_DATE                        TYPE        SYDATE
* | [<---] EV_TIME                        TYPE        SYUZEIT
* | [<---] EV_MSEC                        TYPE        NUM03
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD convert_json_datetime_to_abap.DATA:lv_date      TYPE sy-datum,lv_days_i    TYPE i,lv_sec_i     TYPE i,lv_timestamp TYPE timestampl,lv_timsmsec  TYPE timestampl.CONSTANTS:lc_day_in_sec TYPE i VALUE 86400.CHECK iv_timestamp IS NOT INITIAL.
* IV_TIMESTAMP stores milliseconds since January 1, 1970, 00:00:00 GMTlv_timestamp = iv_timestamp / 1000.   "timestamp in seconds
* One day has 86400 seconds: Timestamp in dayslv_days_i    = lv_timestamp DIV lc_day_in_sec.lv_date      = '19700101'.ev_date     = lv_date + lv_days_i.
* Rest seconds (timestamp - days)lv_sec_i    = lv_timestamp MOD lc_day_in_sec.ev_time     = lv_sec_i.
* Rest sec and milli secondslv_timsmsec  = lv_timestamp MOD lc_day_in_sec.lv_timsmsec  = lv_timsmsec - lv_sec_i.ev_msec      = lv_timsmsec * 1000.*    转换为用户时区时间DATA:lv_tstp TYPE timestamp,lv_zone TYPE sy-zonlo VALUE 'UTC'.CONVERT DATE ev_date TIME ev_time INTO TIME STAMP lv_tstp TIME ZONE lv_zone .CONVERT TIME STAMP lv_tstp TIME ZONE sy-zonloINTO DATE ev_date TIME ev_time.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON_HANDLER=>DESERIALIZE_ID
* +-------------------------------------------------------------------------------------------------+
* | [--->] JSON                           TYPE        STRING
* | [<-->] PARAMTAB                       TYPE        ABAP_FUNC_PARMBIND_TAB
* | [!CX!] ZCX_JSON
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD deserialize_id.
*/***********************************************************/*
*/ New method using the built-in transformation              /*
*/ included in releases 7.02 and 7.03/7.31 (Kernelpatch 116) /*
*/***********************************************************/*TYPE-POOLS: abap.** Remember function parameter types
**constants:
**  abap_func_exporting type abap_func_parmbind-kind value 10,
**  abap_func_importing type abap_func_parmbind-kind value 20,
**  abap_func_tables    type abap_func_parmbind-kind value 30,
**  abap_func_changing  type abap_func_parmbind-kind value 40.DATA:rtab       TYPE abap_trans_resbind_tab,rlin       TYPE abap_trans_resbind,oexcp      TYPE REF TO cx_root,etext      TYPE string,json_xtext TYPE xstring.FIELD-SYMBOLS <parm> TYPE abap_func_parmbind.IF json IS INITIAL. EXIT. ENDIF.  " exit method if there is nothing to parse" build rtab table for transformation idLOOP AT paramtab ASSIGNING <parm>.IF <parm>-kind EQ abap_func_importing. "" va al revés, cuidado!!!CONTINUE.ENDIF.rlin-name  = <parm>-name.rlin-value = <parm>-value.APPEND rlin TO rtab.ENDLOOP." Convert input JSON variable names to uppercaseDATA: reader       TYPE REF TO if_sxml_reader,writer       TYPE REF TO if_sxml_writer,writer_str   TYPE REF TO cl_sxml_string_writer,node         TYPE REF TO if_sxml_node,open_element TYPE REF TO if_sxml_open_element,attributes   TYPE if_sxml_attribute=>attributes.FIELD-SYMBOLS  <attribute> TYPE LINE OF if_sxml_attribute=>attributes.json_xtext = cl_abap_codepage=>convert_to( json ).reader = cl_sxml_string_reader=>create( json_xtext ).writer ?= cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).DO.node = reader->read_next_node( ).IF node IS INITIAL.EXIT.ENDIF.IF node->type = if_sxml_node=>co_nt_element_open.open_element ?= node.attributes  = open_element->get_attributes( ).LOOP AT attributes ASSIGNING <attribute>.IF <attribute>->qname-name = 'name'.<attribute>->set_value(to_upper( <attribute>->get_value( ) ) ).ENDIF.ENDLOOP.ENDIF.writer->write_node( node ).ENDDO.writer_str ?= writer.json_xtext = writer_str->get_output( ) .TRY.CALL TRANSFORMATION id SOURCE XML json_xtextRESULT (rtab).CATCH cx_root INTO oexcp.etext = oexcp->if_message~get_text( ).RAISE EXCEPTION TYPE zcx_jsonEXPORTINGmessage = etext.ENDTRY.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON_HANDLER=>JSON2ABAP
* +-------------------------------------------------------------------------------------------------+
* | [--->] JSON_STRING                    TYPE        STRING(optional)
* | [--->] VAR_NAME                       TYPE        STRING(optional)
* | [--->] PROPERTY_PATH                  TYPE        STRING (default ='json_obj')
* | [<---] PROPERTY_TABLE                 TYPE        JS_PROPERTY_TAB
* | [<-->] JS_OBJECT                      TYPE REF TO CL_JAVA_SCRIPT
* | [<-->] ABAP_DATA                      TYPE        ANY(optional)
* | [!CX!] ZCX_JSON
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD json2abap.
*/************************************************/*
*/ Input any abap data and this method tries to   /*
*/ fill it with the data in the JSON string.      /*
*/  Thanks to Juan Diaz for helping here!!        /*
*/************************************************/*TYPE-POOLS: abap, js.DATA:js_script         TYPE string,js_started        TYPE i VALUE 0,l_json_string     TYPE string,js_property_table TYPE   js_property_tab,js_property       TYPE LINE OF js_property_tab,l_property_path   TYPE string,compname          TYPE string,item_path         TYPE string.DATA:l_type   TYPE c,l_value  TYPE string,linetype TYPE string,l_comp   TYPE LINE OF abap_compdescr_tab.DATA:datadesc TYPE REF TO cl_abap_typedescr,drefdesc TYPE REF TO cl_abap_typedescr,linedesc TYPE REF TO cl_abap_typedescr,strudesc TYPE REF TO cl_abap_structdescr,tabldesc TYPE REF TO cl_abap_tabledescr.DATA newline TYPE REF TO data.FIELD-SYMBOLS:<abap_data> TYPE any,<itab>      TYPE ANY TABLE,<comp>      TYPE any,<jsprop>    TYPE LINE OF js_property_tab,<abapcomp>  TYPE abap_compdescr.DEFINE assign_scalar_value."   &1   <abap_data>"   &2   js_property-valueDESCRIBE FIELD &1 TYPE l_type.l_value = &2.
* convert or adapt scalar values to ABAP.CASE l_type.WHEN 'D'. " date typeIF l_value CS '-'.REPLACE ALL OCCURRENCES OF '-' IN l_value WITH space.CONDENSE l_value NO-GAPS.ENDIF.WHEN 'T'. " time typeIF l_value CS ':'.REPLACE ALL OCCURRENCES OF ':' IN l_value WITH space.CONDENSE l_value NO-GAPS.ENDIF.WHEN OTHERS." may be other conversions or checks could be implemented here.ENDCASE.&1 = l_value.end-of-definition.IF js_object IS NOT BOUND.IF json_string IS INITIAL. EXIT. ENDIF. " exit method if there is nothing to parsel_json_string = json_string." js_object = cl_java_script=>create( STACKSIZE = 16384 ).js_object = cl_java_script=>create( stacksize = 16384 heapsize = 960000 ).***************************************************
*  Parse JSON using JavaScript                    *
***************************************************js_object->bind( EXPORTING name_obj = 'abap_data' name_prop = 'json_string'    CHANGING data = l_json_string ).js_object->bind( EXPORTING name_obj = 'abap_data' name_prop = 'script_started' CHANGING data = js_started ).* We use the JavaScript engine included in ABAP to read the JSON string.
* We simply use the recommended way to eval a JSON string as specified
* in RFC 4627 (http://www.ietf.org/rfc/rfc4627.txt).
*
* Security considerations:
*
*   Generally there are security issues with scripting languages.  JSON
*   is a subset of JavaScript, but it is a safe subset that excludes
*   assignment and invocation.
*
*   A JSON text can be safely passed into JavaScript's eval() function
*   (which compiles and executes a string) if all the characters not
*   enclosed in strings are in the set of characters that form JSON
*   tokens.  This can be quickly determined in JavaScript with two
*   regular expressions and calls to the test and replace methods.
*
*      var my_JSON_object = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
*             text.replace(/"(\\.|[^"\\])*"/g, ''))) &&
*         eval('(' + text + ')');CONCATENATE'var json_obj; ''var json_text; ''function start() { ''  if(abap_data.script_started) { return; } ''  json_text = abap_data.json_string;''  json_obj = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test( ''      json_text.replace(/"(\\.|[^"\\])*"/g, ''''))) && ''    eval(''('' + json_text + '')''); ''  abap_data.script_started = 1; ''} ''if(!abap_data.script_started) start(); 'INTO js_script RESPECTING BLANKS SEPARATED BY xnl.js_object->compile( script_name = 'json_parser'     script = js_script ).js_object->execute( script_name = 'json_parser' ).IF js_object->last_error_message IS NOT INITIAL.RAISE EXCEPTION TYPE zcx_jsonEXPORTINGmessage = js_object->last_error_message.ENDIF.ENDIF.
** End of JS processing.**IF var_name IS NOT INITIAL.CONCATENATE property_path var_name INTO l_property_path SEPARATED BY '.'.ELSE.l_property_path = property_path.ENDIF.
**
**js_property_table = js_object->get_properties_scope_global( property_path = l_property_path ).property_table = js_property_table.* Exit if abap_data is not supplied, normally when called
* from json_deserialize to get top level propertiesIF abap_data IS NOT SUPPLIED.EXIT.ENDIF. "****
* Get ABAP data type, dereference if necessary and startdatadesc = cl_abap_typedescr=>describe_by_data( abap_data ).IF datadesc->kind EQ cl_abap_typedescr=>kind_ref.ASSIGN abap_data->* TO <abap_data>.ELSE.ASSIGN abap_data TO <abap_data>.ENDIF.datadesc = cl_abap_typedescr=>describe_by_data( <abap_data> ).CASE datadesc->kind.WHEN cl_abap_typedescr=>kind_elem.
* Scalar: process ABAP elements. Assume no type conversions for the moment.IF var_name IS INITIAL.RAISE EXCEPTION TYPE zcx_jsonEXPORTINGmessage = 'VAR_NAME is required for scalar values.'.ENDIF.js_property_table = js_object->get_properties_scope_global( property_path = property_path ).READ TABLE js_property_table WITH KEY name = var_name INTO js_property.IF sy-subrc EQ 0.assign_scalar_value <abap_data> js_property-value.ENDIF.WHEN cl_abap_typedescr=>kind_struct.
* Process ABAP structuresstrudesc ?= datadesc.LOOP AT js_property_table ASSIGNING <jsprop>.compname = <jsprop>-name.TRANSLATE compname TO UPPER CASE.READ TABLE strudesc->components WITH KEY name = compname INTO l_comp.IF sy-subrc EQ 0.ASSIGN COMPONENT l_comp-name OF STRUCTURE <abap_data> TO <comp>.CASE l_comp-type_kind.WHEN    cl_abap_typedescr=>typekind_struct1  " 'v'OR cl_abap_typedescr=>typekind_struct2  " 'u'OR cl_abap_typedescr=>typekind_table.   " 'h' (may need a different treatment one day)CONCATENATE l_property_path <jsprop>-name INTO item_path SEPARATED BY '.'.
*> Recursive call herejson2abap( EXPORTING property_path = item_path CHANGING abap_data = <comp> js_object = js_object ).WHEN OTHERS.
* Process scalars in structures (same as the kind_elem above)assign_scalar_value <comp> <jsprop>-value.ENDCASE.ENDIF.ENDLOOP.WHEN cl_abap_typedescr=>kind_table.
* Process ABAP tablesIF js_property_table IS NOT INITIAL.tabldesc ?= datadesc.linedesc = tabldesc->get_table_line_type( ).linetype = linedesc->get_relative_name( ).ASSIGN <abap_data> TO <itab>.LOOP AT js_property_table INTO js_property WHERE name NE 'length'. " the JS object lengthCREATE DATA newline TYPE (linetype).ASSIGN newline->* TO <comp>.CASE js_property-kind.WHEN 'O'.CONCATENATE l_property_path js_property-name INTO item_path SEPARATED BY '.'.CONDENSE item_path.
*> Recursive call herejson2abap( EXPORTING property_path = item_path CHANGING abap_data = newline js_object = js_object ).WHEN OTHERS. " Assume scalars, 'S', 'I', or other JS types" Process scalars in plain table components(same as the kind_elem above)assign_scalar_value <comp> js_property-value.ENDCASE.INSERT <comp> INTO TABLE <itab>.FREE newline.ENDLOOP.ENDIF.WHEN OTHERS. " kind_class, kind_intf" forget it.ENDCASE.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON_HANDLER=>JSON_DESERIALIZE
* +-------------------------------------------------------------------------------------------------+
* | [--->] JSON                           TYPE        STRING
* | [<-->] PARAMTAB                       TYPE        ABAP_FUNC_PARMBIND_TAB
* | [EXC!] ZCX_JSON
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD json_deserialize.TYPE-POOLS: abap, js.** Remember function parameter types
**constants:
**  abap_func_exporting type abap_func_parmbind-kind value 10,
**  abap_func_importing type abap_func_parmbind-kind value 20,
**  abap_func_tables    type abap_func_parmbind-kind value 30,
**  abap_func_changing  type abap_func_parmbind-kind value 40.DATA paramname   TYPE string.DATA js_obj      TYPE REF TO cl_java_script.DATA js_prop_tab TYPE js_property_tab.FIELD-SYMBOLS <js_prop> TYPE LINE OF js_property_tab.FIELD-SYMBOLS <parm>    TYPE abap_func_parmbind.IF json IS INITIAL. EXIT. ENDIF.json2abap( EXPORTING json_string = json  IMPORTING property_table = js_prop_tab  CHANGING js_object = js_obj ).LOOP AT js_prop_tab ASSIGNING <js_prop>.paramname = <js_prop>-name.TRANSLATE paramname TO UPPER CASE.READ TABLE paramtab WITH KEY name = paramname ASSIGNING <parm>.IF sy-subrc EQ 0.IF <parm>-kind NE abap_func_importing. "" va al revés, cuidado!!!json2abap( EXPORTING var_name = <js_prop>-name  CHANGING abap_data = <parm>-value js_object = js_obj ).ENDIF.ENDIF.ENDLOOP.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_JSON_HANDLER->NOTES
* +-------------------------------------------------------------------------------------------------+
* | [<-()] TEXT                           TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD notes.DATA location TYPE string.CONCATENATE me->my_url me->my_service '/RFC_SYSTEM_INFO' INTO location.CONCATENATE'<html><head><title>JSON (NEW) handler notes</title></head><body>''<h4>About this service...</h4>''This is the ABAP implementation of a conversion program that'' tranforms ABAP data into a <a href="http://www.json.org">JSON</a> representation.''<p>''It provides a user interface in the form of a ICF service that ''allows web invocation of ABAP function modules. It doesn''t matter if they are RFC enabled or not.''<p>In this system this service has ''been assigned to ICF service <a href="' me->my_url me->my_service '">' me->my_service '</a>.''<p>''In order to invoke a function module, just put its name in the PATH_INFO ''of the service URL, as is shown in the following examples.''<p>Try the following link to do the default call in JSON format:<pre><a href="' location '?format=json">'location'?format=json</a></pre>''<p>A simple syntax allows to get the output in different formats.<p>''The following gets the output in <a href="http://yaml.org">YAML</a> format:''<pre><a href="' location '?format=yaml">'location'?format=yaml</a></pre>''''<p>And this will get the output in a basic XML representation: <pre><a href="' location '?format=xml">'location'?format=xml</a></pre>''<p>And, just for fun, getting it into Perl format could be handy: <pre><a href="' location '?format=perl">'location'?format=perl</a></pre>''<p>Finnally, you can add a callback to get the JSON response enclosed in a javascript function call,'' in order to allow a <a href="http://en.wikipedia.org/wiki/JSONP">JSONP</a> style response: ''<pre><a href="'location '?format=json&callback=callMe">'location '?format=json&callback=callMe</a></pre>''<hr><h4>WARNING</h4>This is work in progress and may not be suitable for use in productive ''systems. The interface is somewhat unstable. Please feel free to test it and report  ''any bug and improvement you may find.''<p>Use it at your own risk!''<p>For more information: <a href="https://cw.sdn.sap.com/cw/groups/json-adapter-for-abap-function-modules">''https://cw.sdn.sap.com/cw/groups/json-adapter-for-abap-function-modules</a>''<p>''If you have any questions, please contact me at <a href="mailto:cesar.martin@sap.com">''cesar.martin@sap.com</a>''<p>''<hr></body></html>'INTO text RESPECTING BLANKS.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON_HANDLER=>SERIALIZE_ID
* +-------------------------------------------------------------------------------------------------+
* | [--->] PARAMTAB                       TYPE        ABAP_FUNC_PARMBIND_TAB
* | [--->] PARAMS                         TYPE        ANY(optional)
* | [--->] EXCEPTAB                       TYPE        ABAP_FUNC_EXCPBIND_TAB(optional)
* | [--->] SHOW_IMPP                      TYPE        ABAP_BOOL(optional)
* | [--->] JSONP                          TYPE        STRING(optional)
* | [--->] LOWERCASE                      TYPE        ABAP_BOOL (default =ABAP_FALSE)
* | [--->] FORMAT                         TYPE        STRING (default ='JSON')
* | [--->] FUNCNAME                       TYPE        RS38L_FNAM(optional)
* | [--->] CAMELCASE                      TYPE        ABAP_BOOL (default =ABAP_FALSE)
* | [<---] O_STRING                       TYPE        STRING
* | [!CX!] ZCX_JSON
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD serialize_id.
*/***********************************************************/*
*/ New method using the built-in transformation              /*
*/ included in releases 7.02 and 7.03/7.31 (Kernelpatch 116) /*
*/ Generates both JSON and XML formats!!
*/***********************************************************/*
*/
** Remember function parameter types
**constants:
**  abap_func_exporting type abap_func_parmbind-kind value 10,
**  abap_func_importing type abap_func_parmbind-kind value 20,
**  abap_func_tables    type abap_func_parmbind-kind value 30,
**  abap_func_changing  type abap_func_parmbind-kind value 40.TYPE-POOLS: abap.DATA:stab        TYPE abap_trans_srcbind_tab,slin        TYPE abap_trans_srcbind,oexcp       TYPE REF TO cx_root,etext       TYPE string,adata       TYPE REF TO data,json_writer TYPE REF TO cl_sxml_string_writer.FIELD-SYMBOLS <parm> TYPE abap_func_parmbind.
*  field-symbols <excep> type abap_func_excpbind.LOOP AT paramtab ASSIGNING <parm>.IF show_impp NE 'X'AND <parm>-kind EQ abap_func_exporting. "" va al revés, cuidado!!!CONTINUE.ENDIF.slin-name  = <parm>-name.slin-value = <parm>-value.APPEND slin TO stab. CLEAR slin.ENDLOOP.IF exceptab IS NOT INITIAL.slin-name  = 'EXCEPTION'.GET REFERENCE OF exceptab INTO adata.slin-value = adata.APPEND slin TO stab. CLEAR slin.ENDIF.json_writer = cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).TRY.CASE format.WHEN 'XML'.CALL TRANSFORMATION id OPTIONS data_refs = 'embedded'initial_components = 'include'SOURCE (stab)RESULT XML o_string.WHEN OTHERS.CALL TRANSFORMATION id OPTIONS data_refs = 'embedded'initial_components = 'include'SOURCE (stab)RESULT XML json_writer.o_string = cl_abap_codepage=>convert_from( json_writer->get_output( ) ).
*  json_string = json_writer->get_output( ).IF jsonp IS NOT INITIAL.CONCATENATE jsonp '(' o_string ');' INTO o_string.ENDIF.ENDCASE.CATCH cx_root INTO oexcp.etext = oexcp->if_message~get_text( ).RAISE EXCEPTION TYPE zcx_jsonEXPORTINGmessage = etext.ENDTRY.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON_HANDLER=>SERIALIZE_JSON
* +-------------------------------------------------------------------------------------------------+
* | [--->] PARAMTAB                       TYPE        ABAP_FUNC_PARMBIND_TAB
* | [--->] PARAMS                         TYPE        ANY(optional)
* | [--->] EXCEPTAB                       TYPE        ABAP_FUNC_EXCPBIND_TAB(optional)
* | [--->] SHOW_IMPP                      TYPE        ABAP_BOOL(optional)
* | [--->] JSONP                          TYPE        STRING(optional)
* | [--->] LOWERCASE                      TYPE        ABAP_BOOL (default =ABAP_FALSE)
* | [--->] CAMELCASE                      TYPE        ABAP_BOOL (default =ABAP_FALSE)
* | [<---] O_STRING                       TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD serialize_json.
* ABAP based JSON serializer for function modules (January 2013).TYPE-POOLS: abap.** Remember function parameter types
**constants:
**  abap_func_exporting type abap_func_parmbind-kind value 10,
**  abap_func_importing type abap_func_parmbind-kind value 20,
**  abap_func_tables    type abap_func_parmbind-kind value 30,
**  abap_func_changing  type abap_func_parmbind-kind value 40.DATA json_fragments TYPE TABLE OF string.DATA rec_json_string TYPE string.DATA paramname TYPE string.DATA l_lines TYPE i.DATA l_index TYPE i.DATA upcase TYPE xfeld VALUE 'X'.FIELD-SYMBOLS <parm> TYPE abap_func_parmbind.FIELD-SYMBOLS <excep> TYPE abap_func_excpbind.IF jsonp IS NOT INITIAL.APPEND jsonp TO json_fragments.APPEND '(' TO json_fragments.ENDIF.rec_json_string = '{'.APPEND rec_json_string TO json_fragments.CLEAR rec_json_string.CLEAR l_index.l_lines = lines( paramtab ).LOOP AT paramtab ASSIGNING <parm>.IF show_impp NE 'X'AND <parm>-kind EQ abap_func_exporting. "" va al revés, cuidado!!!SUBTRACT 1 FROM l_lines.CONTINUE.ENDIF.ADD 1 TO l_index.paramname = <parm>-name.IF lowercase EQ abap_true.TRANSLATE paramname TO LOWER CASE." paramname = to_lower( paramname ).upcase = space.ENDIF.IF camelcase EQ abap_true.paramname = to_mixed( val = paramname  case = 'a').ENDIF.rec_json_string = abap2json( abap_data = <parm>-value  name = paramname  upcase = upcase camelcase = camelcase ).APPEND rec_json_string TO json_fragments.CLEAR rec_json_string.IF l_index < l_lines.APPEND ',' TO json_fragments .ENDIF .ENDLOOP.IF exceptab IS NOT INITIAL.IF l_lines GT 0.APPEND ',' TO json_fragments.ENDIF.rec_json_string = abap2json( abap_data = exceptab upcase = 'X' name = 'EXCEPTION').APPEND rec_json_string TO json_fragments.CLEAR rec_json_string.ENDIF.rec_json_string = '}'.APPEND rec_json_string TO json_fragments.CLEAR rec_json_string.IF jsonp IS NOT INITIAL.APPEND ');' TO json_fragments.ENDIF.CONCATENATE LINES OF json_fragments INTO o_string.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON_HANDLER=>SERIALIZE_PERL
* +-------------------------------------------------------------------------------------------------+
* | [--->] PARAMTAB                       TYPE        ABAP_FUNC_PARMBIND_TAB
* | [--->] PARAMS                         TYPE        ANY(optional)
* | [--->] EXCEPTAB                       TYPE        ABAP_FUNC_EXCPBIND_TAB(optional)
* | [--->] SHOW_IMPP                      TYPE        ABAP_BOOL(optional)
* | [--->] JSONP                          TYPE        STRING(optional)
* | [--->] LOWERCASE                      TYPE        ABAP_BOOL (default =ABAP_FALSE)
* | [--->] FUNCNAME                       TYPE        RS38L_FNAM
* | [<---] PERL_STRING                    TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD serialize_perl.
* Just for fun, generate data in Perl Data::Dumper format.TYPE-POOLS: abap.**Remember function parameter types
**constants:
**  abap_func_exporting type abap_func_parmbind-kind value 10,
**  abap_func_importing type abap_func_parmbind-kind value 20,
**  abap_func_tables    type abap_func_parmbind-kind value 30,
**  abap_func_changing  type abap_func_parmbind-kind value 40.DATA perl_fragments TYPE TABLE OF string.DATA rec_perl_string TYPE string.DATA paramname TYPE string.DATA l_lines TYPE i.DATA l_index TYPE i.DATA upcase TYPE xfeld VALUE 'X'.DATA perl_var TYPE string.FIELD-SYMBOLS <parm> TYPE abap_func_parmbind.FIELD-SYMBOLS <excep> TYPE abap_func_excpbind.IF jsonp IS NOT INITIAL.perl_var = jsonp.ELSE.perl_var = funcname.ENDIF.CONCATENATE '$' perl_var ' = {' INTO rec_perl_string.APPEND rec_perl_string TO perl_fragments.CLEAR rec_perl_string.CLEAR l_index.l_lines = lines( paramtab ).LOOP AT paramtab ASSIGNING <parm>.IF show_impp NE 'X'AND <parm>-kind EQ abap_func_exporting. "" va al revés, cuidado!!!SUBTRACT 1 FROM l_lines.CONTINUE.ENDIF.ADD 1 TO l_index.paramname = <parm>-name.IF lowercase EQ abap_true.TRANSLATE paramname TO LOWER CASE.upcase = space.ENDIF.rec_perl_string = abap2perl( abap_data = <parm>-value  name = paramname  upcase = upcase ).APPEND rec_perl_string TO perl_fragments.CLEAR rec_perl_string.IF l_index < l_lines.APPEND ',' TO perl_fragments .ENDIF .ENDLOOP.IF exceptab IS NOT INITIAL.IF l_lines GT 0.APPEND ',' TO perl_fragments.ENDIF.rec_perl_string = abap2perl( abap_data = exceptab upcase = 'X' name = 'EXCEPTION').APPEND rec_perl_string TO perl_fragments.CLEAR rec_perl_string.ENDIF.rec_perl_string = '};'.APPEND rec_perl_string TO perl_fragments.CLEAR rec_perl_string.CONCATENATE LINES OF perl_fragments INTO perl_string.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON_HANDLER=>SERIALIZE_XML
* +-------------------------------------------------------------------------------------------------+
* | [--->] PARAMTAB                       TYPE        ABAP_FUNC_PARMBIND_TAB
* | [--->] PARAMS                         TYPE        ANY(optional)
* | [--->] EXCEPTAB                       TYPE        ABAP_FUNC_EXCPBIND_TAB(optional)
* | [--->] SHOW_IMPP                      TYPE        ABAP_BOOL(optional)
* | [--->] JSONP                          TYPE        STRING(optional)
* | [--->] FUNCNAME                       TYPE        RS38L_FNAM
* | [--->] LOWERCASE                      TYPE        ABAP_BOOL (default =ABAP_FALSE)
* | [--->] FORMAT                         TYPE        STRING
* | [<---] O_STRING                       TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD serialize_xml.
* Serialize function data into simple XML
*/ Look at method serialize_id for a new way of doing XML.TYPE-POOLS: abap.** Remember function parameter types
***constants:
***  abap_func_exporting type abap_func_parmbind-kind value 10,
***  abap_func_importing type abap_func_parmbind-kind value 20,
***  abap_func_tables    type abap_func_parmbind-kind value 30,
***  abap_func_changing  type abap_func_parmbind-kind value 40.DATA rec_xml_string TYPE string.DATA xml_fragments TYPE TABLE OF string.DATA l_funcname TYPE string.DATA paramname TYPE string.FIELD-SYMBOLS <parm> TYPE abap_func_parmbind.FIELD-SYMBOLS <excep> TYPE abap_func_excpbind.DATA upcase TYPE xfeld VALUE 'X'.CONSTANTS:xml_head TYPE string VALUE '<?xml version="1.0" encoding="utf-8"?>'.APPEND xml_head TO xml_fragments.l_funcname = funcname.IF lowercase EQ abap_true.TRANSLATE l_funcname TO LOWER CASE.upcase = space.ENDIF.CONCATENATE '<' l_funcname '>' INTO rec_xml_string.APPEND rec_xml_string TO xml_fragments.LOOP AT paramtab ASSIGNING <parm>.IF show_impp NE 'X'AND <parm>-kind EQ abap_func_exporting. "" va al revés, cuidado!!!CONTINUE.ENDIF.paramname = <parm>-name.IF lowercase EQ abap_true.TRANSLATE paramname TO LOWER CASE.ENDIF.rec_xml_string = abap2xml( name = paramname abap_data = <parm>-value upcase = upcase ).APPEND rec_xml_string TO xml_fragments.ENDLOOP.IF exceptab IS NOT INITIAL.rec_xml_string = abap2xml( name = 'EXCEPTION' abap_data = exceptab  upcase = upcase ).APPEND rec_xml_string TO xml_fragments.ENDIF.CONCATENATE '</' l_funcname '>' INTO rec_xml_string.APPEND rec_xml_string TO xml_fragments.CONCATENATE LINES OF xml_fragments INTO o_string.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON_HANDLER=>SERIALIZE_YAML
* +-------------------------------------------------------------------------------------------------+
* | [--->] PARAMTAB                       TYPE        ABAP_FUNC_PARMBIND_TAB
* | [--->] PARAMS                         TYPE        ANY
* | [--->] EXCEPTAB                       TYPE        ABAP_FUNC_EXCPBIND_TAB
* | [--->] SHOW_IMPP                      TYPE        ABAP_BOOL
* | [--->] JSONP                          TYPE        STRING
* | [--->] LOWERCASE                      TYPE        ABAP_BOOL (default =ABAP_FALSE)
* | [<---] YAML_STRING                    TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD serialize_yaml.
* Now, go and represent function data in YAML (http://yaml.org)TYPE-POOLS: abap.
** Remember function parameter types
**constants:
**  abap_func_exporting type abap_func_parmbind-kind value 10,
**  abap_func_importing type abap_func_parmbind-kind value 20,
**  abap_func_tables    type abap_func_parmbind-kind value 30,
**  abap_func_changing  type abap_func_parmbind-kind value 40.DATA yaml_fragments TYPE TABLE OF string.DATA rec_yaml_string TYPE string.DATA rec_yaml_table TYPE TABLE OF string.DATA paramname TYPE string.FIELD-SYMBOLS <parm> TYPE abap_func_parmbind.FIELD-SYMBOLS <excep> TYPE abap_func_excpbind.DATA upcase TYPE xfeld VALUE 'X'.DATA yaml_head TYPE string VALUE '--- #YAML:1.0'.CONCATENATE yaml_head xnl INTO rec_yaml_string.APPEND rec_yaml_string TO yaml_fragments.CLEAR rec_yaml_string.LOOP AT paramtab ASSIGNING <parm>.IF show_impp NE 'X'AND <parm>-kind EQ abap_func_exporting. "" va al revés, cuidado!!!CONTINUE.ENDIF.paramname = <parm>-name.IF lowercase EQ abap_true.TRANSLATE paramname TO LOWER CASE.upcase = space.ENDIF.rec_yaml_string = abap2yaml( abap_data = <parm>-value  name = paramname upcase = upcase ).APPEND rec_yaml_string TO yaml_fragments.CLEAR rec_yaml_string.ENDLOOP.IF exceptab IS NOT INITIAL.rec_yaml_string = abap2yaml( abap_data = exceptab name = 'EXCEPTION' upcase = 'X' ).APPEND rec_yaml_string TO yaml_fragments.CLEAR rec_yaml_string.ENDIF.*  append xnl to yaml_fragments.CONCATENATE LINES OF yaml_fragments INTO yaml_string.*  if jsonp is not initial.
*     concatenate jsonp '(' yaml_string ');' into yaml_string.
*  endif.ENDMETHOD.
ENDCLASS.

工具类

zcl_log_handler 保存日志

CLASS zcl_log_handler DEFINITIONPUBLICFINALCREATE PUBLIC .PUBLIC SECTION.TYPE-POOLS abap .METHODS constructorIMPORTING!function_name TYPE rs38l_fnam .METHODS add_paramaterIMPORTING!name  TYPE abap_parmname!value TYPE anyRAISINGcx_ai_system_fault .METHODS save_logIMPORTING!is_input TYPE zif_msg .PROTECTED SECTION.PRIVATE SECTION.DATA paramtab TYPE abap_func_parmbind_tab .DATA exceptab TYPE abap_func_excpbind_tab .DATA:t_params_p TYPE TABLE OF rfc_fint_p .DATA gs_ifcfg TYPE zif_ifcfg .DATA gs_iffn TYPE zif_iffn .
ENDCLASS.CLASS zcl_log_handler IMPLEMENTATION.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_LOG_HANDLER->ADD_PARAMATER
* +-------------------------------------------------------------------------------------------------+
* | [--->] NAME                           TYPE        ABAP_PARMNAME
* | [--->] VALUE                          TYPE        ANY
* | [!CX!] CX_AI_SYSTEM_FAULT
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD add_paramater.FIELD-SYMBOLS <parm> TYPE abap_func_parmbind.READ TABLE paramtab ASSIGNING <parm> WITH KEY name = name.IF sy-subrc = 0.GET REFERENCE OF value INTO <parm>-value.ELSE.RAISE EXCEPTION TYPE cx_ai_system_faultEXPORTINGcode      = 'E'errortext = '输入参数不存在'.ENDIF.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_LOG_HANDLER->CONSTRUCTOR
* +-------------------------------------------------------------------------------------------------+
* | [--->] FUNCTION_NAME                  TYPE        RS38L_FNAM
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD constructor.REFRESH:paramtab,exceptab,t_params_p.CALL METHOD zcl_json_handler=>build_paramsEXPORTINGfunction_name          = function_nameIMPORTINGparamtab               = paramtabexceptab               = exceptabparams                 = t_params_pEXCEPTIONSinvalid_function       = 1unsupported_param_type = 2OTHERS                 = 3.IF sy-subrc = 1.RAISE EXCEPTION TYPE cx_ai_system_faultEXPORTINGcode      = 'E'errortext = '函数名错误'.ELSEIF sy-subrc <> 0.RAISE EXCEPTION TYPE cx_ai_system_faultEXPORTINGcode      = 'E'errortext = '函数名错误'.ENDIF.ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_LOG_HANDLER->SAVE_LOG
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_INPUT                       TYPE        ZIF_MSG
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD save_log.DATA:ls_zif_msg TYPE zif_msg.ls_zif_msg = is_input.CALL METHOD zcl_json_handler=>serialize_jsonEXPORTINGparamtab  = paramtabshow_impp = 'X'IMPORTINGo_string  = ls_zif_msg-paylod.MODIFY zif_msg FROM ls_zif_msg.COMMIT WORK .ENDMETHOD.
ENDCLASS.

接口日志展示ALV

report : ZIF_DISPLAY

*& Responsibility
*&---------------------------------------------------------------------*
* Program Name:ZIF_DISPLAY
* Date written:
* Author's name:
* Last update:
* Program title:接口日志查询
* Project Name:
* Version:
*&---------------------------------------------------------------------*
* Description: (Incl. Related Function Area and System)
*&---------------------------------------------------------------------*
*
*&---------------------------------------------------------------------*
* Change History
*&---------------------------------------------------------------------*
*     Date   |   Programmer   |   Corr. #   |   Description
*            |                |             |
*            |                |             |
*&---------------------------------------------------------------------*
REPORT zif_display.DATA: gt_itab TYPE STANDARD TABLE OF zif_msg.*---------------------------------------------------------------------*
* 选择屏幕
*---------------------------------------------------------------------*
TABLES:usr02.
SELECTION-SCREEN:BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.SELECT-OPTIONS:s_erdat FOR sy-datum,s_ernam FOR usr02-bname.
SELECTION-SCREEN END OF BLOCK b1.*&---------------------------------------------------------------------*
*&      START-OF-SELECTION
*&---------------------------------------------------------------------*
START-OF-SELECTION.PERFORM get_data.PERFORM display.FORM get_data .SELECT *FROM zif_msgINTO TABLE gt_itabWHERE erdat IN s_erdatAND   ernam IN s_ernam.SORT gt_itab BY erdat DESCENDING uzeit DESCENDING.ENDFORM.                    "GET_DATA*&---------------------------------------------------------------------*
*& Form display
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM display .DATA:ls_layout     TYPE lvc_s_layo.ls_layout-zebra = 'X'.ls_layout-cwidth_opt = 'X'.ls_layout-sel_mode = 'B'.CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'EXPORTINGi_callback_program      = sy-repidi_callback_user_command = 'FRM_USER_COMMAND'is_layout_lvc           = ls_layouti_structure_name        = 'ZIF_MSG'
*     it_fieldcat_lvc         = gt_fieldcati_save                  = 'A'TABLESt_outtab                = gt_itabEXCEPTIONSprogram_error           = 1OTHERS                  = 2.IF sy-subrc <> 0.MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgnoWITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.ENDIF.ENDFORM.FORM frm_user_command USING iv_ucomm       TYPE sy-ucommis_selfield     TYPE slis_selfield.DATA: l_grid  TYPE REF TO cl_gui_alv_grid.CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'IMPORTINGe_grid = l_grid.CALL METHOD l_grid->check_changed_data.CASE iv_ucomm.WHEN '&IC1'.READ TABLE gt_itab INDEX  is_selfield-tabindex INTO DATA(ls_itab).  "获取单击行IF sy-subrc IS INITIAL.PERFORM display_json  USING ls_itab.ENDIF.*  WHEN '&RESEND'.重新发送*      DATA:lt_para_tab  TYPE abap_func_parmbind_tab,
*           ls_para_line LIKE LINE OF lt_para_tab,
*           lt_exceptab  TYPE abap_func_excpbind_tab,
*           lt_params_p  TYPE TABLE OF rfc_fint_p,
*           params_p     TYPE rfc_fint_p,
*           oexcp        TYPE REF TO cx_root,
*           lv_etext     TYPE string.
*      FIELD-SYMBOLS <parm> TYPE abap_func_parmbind.
*      CALL METHOD zcl_json_handler=>build_params
*        EXPORTING
*          function_name          = ls_itab-proname
*        IMPORTING
*          paramtab               = lt_para_tab
*          exceptab               = lt_exceptab
*          params                 = lt_params_p
*        EXCEPTIONS
*          invalid_function       = 1
*          unsupported_param_type = 2
*          OTHERS                 = 3.
*      IF sy-subrc <> 0.
*        CONCATENATE '函数名错误. ' sy-msgid sy-msgty sy-msgno ': '
*                sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
*                INTO lv_etext SEPARATED BY '-'.
*        MESSAGE lv_etext TYPE 'E'.
*      ENDIF.
*      TRY.
*          CALL METHOD zcl_json_handler=>json_deserialize
*            EXPORTING
*              json     = ls_itab-paylod
*            CHANGING
*              paramtab = lt_para_tab.
*          TRY.
*              CALL FUNCTION ls_itab-proname
*                PARAMETER-TABLE lt_para_tab
*                EXCEPTION-TABLE lt_exceptab.
*            CATCH cx_root INTO oexcp.
*              lv_etext = oexcp->if_message~get_longtext(  preserve_newlines = abap_true ).
*              MESSAGE lv_etext TYPE 'E'.
*
*          ENDTRY.
*        CATCH cx_root INTO oexcp.
*          lv_etext = oexcp->if_message~get_text( ).
*          MESSAGE lv_etext TYPE 'E'.
*      ENDTRY.ENDCASE.
**刷新CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'IMPORTINGe_grid = l_grid.CALL METHOD l_grid->check_changed_data.CALL METHOD l_grid->refresh_table_display.is_selfield-refresh = 'X' .ENDFORM.                    "frm_user_commandFORM display_json  USING    is_itab TYPE zif_msg.DATA:lv_json TYPE string.DATA(out) = cl_demo_output=>new( ).DATA :reader     TYPE REF TO if_sxml_reader,writer     TYPE REF TO if_sxml_writer,writer_str TYPE REF TO cl_sxml_string_writer.DATA json TYPE xstring.lv_json = is_itab-paylod.out->begin_section( |函数:{ is_itab-proname }| ).CHECK lv_json <> ''.IF lv_json+0(1) = '<'.out->write_xml( lv_json ).ELSE.out->write_json( lv_json ).ENDIF.IF sy-subrc <> 0.MESSAGE '要显示的报文不存在!' TYPE 'S'.ELSE.out->display(  ).ENDIF.
ENDFORM.

函数demo

FUNCTION zdemo_02.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(IV_INPUT) TYPE  CHAR10
*"     REFERENCE(IV_INPUT2) TYPE  CHAR10
*"  EXPORTING
*"     REFERENCE(EV_MSG) TYPE  STRING
*"----------------------------------------------------------------------
*初始化获取函数相关自身信息DATA: lt_callstack TYPE abap_callstack.CALL FUNCTION 'SYSTEM_CALLSTACK'IMPORTINGcallstack = lt_callstack.DATA(lv_func_name) = VALUE #( lt_callstack[ 1 ]-blockname OPTIONAL ).SELECT funcname, paramtype, pposition, parameter, structureFROM fupararefWHERE funcname = @lv_func_nameINTO TABLE @DATA(lt_parameters_tab).SORT lt_parameters_tab BY paramtype pposition.
*初始化获取函数相关自身信息TRY.DATA(lv_uuid) = cl_system_uuid=>create_uuid_c32_static( ).CATCH cx_uuid_error.ENDTRY.ev_msg = 'S'.*save logDATA:ls_zif_msg              TYPE zif_msg.DATA:lr_log                  TYPE REF TO zcl_log_handler.DATA:lo_sys_exception2       TYPE REF TO cx_ai_system_fault..ls_zif_msg-guid        = lv_uuid.ls_zif_msg-proname     = 'ZDEMO_02'.ls_zif_msg-erdat       = sy-datum.ls_zif_msg-ernam       = sy-uname.ls_zif_msg-uzeit       = sy-uzeit.ls_zif_msg-type        = ''.ls_zif_msg-msg         = ''.
*  ls_zif_msg-paylod      = lv_uuid.ls_zif_msg-cust_field1 = iv_input.
*  ls_zif_msg-cust_field2 = lv_uuid.
*  ls_zif_msg-cust_field3 = lv_uuid.FIELD-SYMBOLS: </afl/parameter>   TYPE any.TRY.lr_log = NEW #( CONV #( lv_func_name ) ).
*优化写法LOOP AT lt_parameters_tab  ASSIGNING FIELD-SYMBOL(<ls_tab>).ASSIGN (<ls_tab>-parameter) TO </afl/parameter>.lr_log->add_paramater( name = <ls_tab>-parameter value = </afl/parameter> ).ENDLOOP.
*原始写法
*      lr_log->add_paramater( name = 'IV_INPUT' value = iv_input ).
*      lr_log->add_paramater( name = 'EV_MSG'   value = ev_msg ).
**原始写法lr_log->save_log( is_input = ls_zif_msg ).CATCH cx_ai_system_fault INTO lo_sys_exception2.       "ENDTRY.ENDFUNCTION.

SAP ABAP 接口函数日志 简化版相关推荐

  1. SAP ABAP 接口开发(RFC,IDOC,Webservice,Native SQL)

    SAP 常用的接口开发分为几种方式: (1)RFC   (2)W ebservice  (3)IDOC (4)Native SQL 有个视频课程对SAP的这几种接口开发讲的很好,给分享下:SAP AB ...

  2. SAP ABAP 四舍五入函数

    ABAP 中处理数据的函数方法很多,其中涉及到四舍五入的有两个(可能还有更多):ROUND 和 HR_NZ_ROUNDING_DECIMALS 前者位于Basis功能开发包 SZME 里面,在标准中用 ...

  3. sap客户信贷_通过SAP ABAP接口修改客户信贷主数据

    FUNCTION ZSD_CREDITLIMIT_CHANGE. *"------------------------------------------------------------ ...

  4. SAP ABAP 我的文章合集:SAP ERP 与泛微 OA 的系统集成

    SAP ABAP 我的文章合集:SAP ERP 与泛微 OA 的系统集成 简介: 本文章合集收录了我关于 SAP ERP 与泛微 OA 的系统集成相关文章,新的文章会被及时更新到本合集中.SAP ER ...

  5. SAP ABAP 调用 BAPI_GOODSMVT_CREATE 没有执行 MIGO/MB0A 相同检查的问题

    SAP ABAP 调用 BAPI_GOODSMVT_CREATE 没有执行 MIGO/MB0A 相同检查的问题 引言: 调用 MIGO 的BAPI(BAPI_GOODSMVT_CREATE)实现特定业 ...

  6. SAP ABAP ChatGPT 初体验 我会失业吗?

    SAP ABAP ChatGPT 初体验 我会失业吗? 简介: ChatGPT 最近很火,听说我可能要失业!就在今天我历经千辛万苦,终于把 ChatGPT 注册好了.话不多说,我先问两个 ABAP 开 ...

  7. sap abap好用的函数

    函数名 描述 SD_VBAP_READ_WITH_VBELN 根据销售订单读取表vbap中的信息 EDIT_LINES 把READ_TEXT返回的LINES中的行按照TDFORMAT="*& ...

  8. C#如何连接SAP调用SAP接口函数

    在项目中我们经常会遇到SAP与其他应用系统对接的情况,如OA对接SAP的FI.HR模块,生产系统对接SAP的MM模块等等.这里和大家介绍下C#如果调用SAP接口,从而调用SAP接口函数. 下面先贴出代 ...

  9. [转]SAP ABAP中使用Read_Text函数读取项目文本的方法

    SAP ABAP中使用Read_Text函数读取项目文本的方法 使用Read_Text函数来读取文本内容.需要找到相关参数. 下面以采购订单为例: 双击文本,进入文本编辑器. 转到->表头. 显 ...

最新文章

  1. VirtualBox - RTR3InitEx failed with rc=-1912 (rc=-1912)
  2. 2018-4-15狼群算法以及改进的总结
  3. React-Todos
  4. SB Admin 2 学习笔记1
  5. 解决雷达图文字显示不全问题
  6. CentOS 7安装教程(图文详解)如下
  7. Linux服务器---关闭selinux
  8. @requirespermissions注解是什么意思_如何基于spring开发自定义注解实现对接口访问频次限制?...
  9. 路由器安置(Routing)
  10. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol52]38.隐蔽信道和侧信道的区别
  11. python封装举例_Python+Pycharm—学习1—封装导入
  12. EOS Platform 7.2 安装
  13. 拓端tecdat|sas文本挖掘案例:如何使用SAS计算Word Mover的距离
  14. 阶段3 3.SpringMVC·_07.SSM整合案例_08.ssm整合之Spring整合MyBatis框架
  15. Tinker在sdk升级后无法成功打补丁包的问题
  16. 2018湘南学院计算机分数线,湘南学院录取分数线2021是多少分(附历年录取分数线)...
  17. 用C语言实现计算器功能
  18. java 数字信号_GitHub - Bazingaliu/JavaDsp: 数字信号处理(DSP)方面的Java封装,包含常用的一些处理方法,如滤波、信号变换等等。...
  19. 计算机网络中abc类地址,abc类ip地址-abc类ip地址和私有地址范围
  20. 在标准宽带光纤上实现量子加密

热门文章

  1. 除了祈福,我们还可以让消防更智能
  2. 任性动图---制作动图、录屏软件 可方便添加各种文字
  3. CentOS快速搭建服务器 超简单
  4. 为什么至少三个哨兵_部队大门为什么要立一块“哨兵神圣,不可侵犯”的牌子?_知道问答...
  5. bootstrap分页插件php,bootstrap paginator分页插件使用方法
  6. 中国人最常说的‘中国式英语’
  7. 微信开发 - 第三方网站接入微信登录、微信支付时,本地 redirect_uri 参数错误导致无法调试的解决方案(微信开放平台)完美解决每次都需要部署到线上测试,在本地使用本地 ip 就能轻松调试
  8. Mathtype部分数学符号不能显示,只能显示方框时的解决办法
  9. win10 anaconda用conda命令安装
  10. 关于地址栏收藏夹的图标