SAP ABAP 接口函数日志 简化版
日志存储表
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 接口函数日志 简化版相关推荐
- SAP ABAP 接口开发(RFC,IDOC,Webservice,Native SQL)
SAP 常用的接口开发分为几种方式: (1)RFC (2)W ebservice (3)IDOC (4)Native SQL 有个视频课程对SAP的这几种接口开发讲的很好,给分享下:SAP AB ...
- SAP ABAP 四舍五入函数
ABAP 中处理数据的函数方法很多,其中涉及到四舍五入的有两个(可能还有更多):ROUND 和 HR_NZ_ROUNDING_DECIMALS 前者位于Basis功能开发包 SZME 里面,在标准中用 ...
- sap客户信贷_通过SAP ABAP接口修改客户信贷主数据
FUNCTION ZSD_CREDITLIMIT_CHANGE. *"------------------------------------------------------------ ...
- SAP ABAP 我的文章合集:SAP ERP 与泛微 OA 的系统集成
SAP ABAP 我的文章合集:SAP ERP 与泛微 OA 的系统集成 简介: 本文章合集收录了我关于 SAP ERP 与泛微 OA 的系统集成相关文章,新的文章会被及时更新到本合集中.SAP ER ...
- SAP ABAP 调用 BAPI_GOODSMVT_CREATE 没有执行 MIGO/MB0A 相同检查的问题
SAP ABAP 调用 BAPI_GOODSMVT_CREATE 没有执行 MIGO/MB0A 相同检查的问题 引言: 调用 MIGO 的BAPI(BAPI_GOODSMVT_CREATE)实现特定业 ...
- SAP ABAP ChatGPT 初体验 我会失业吗?
SAP ABAP ChatGPT 初体验 我会失业吗? 简介: ChatGPT 最近很火,听说我可能要失业!就在今天我历经千辛万苦,终于把 ChatGPT 注册好了.话不多说,我先问两个 ABAP 开 ...
- sap abap好用的函数
函数名 描述 SD_VBAP_READ_WITH_VBELN 根据销售订单读取表vbap中的信息 EDIT_LINES 把READ_TEXT返回的LINES中的行按照TDFORMAT="*& ...
- C#如何连接SAP调用SAP接口函数
在项目中我们经常会遇到SAP与其他应用系统对接的情况,如OA对接SAP的FI.HR模块,生产系统对接SAP的MM模块等等.这里和大家介绍下C#如果调用SAP接口,从而调用SAP接口函数. 下面先贴出代 ...
- [转]SAP ABAP中使用Read_Text函数读取项目文本的方法
SAP ABAP中使用Read_Text函数读取项目文本的方法 使用Read_Text函数来读取文本内容.需要找到相关参数. 下面以采购订单为例: 双击文本,进入文本编辑器. 转到->表头. 显 ...
最新文章
- VirtualBox - RTR3InitEx failed with rc=-1912 (rc=-1912)
- 2018-4-15狼群算法以及改进的总结
- React-Todos
- SB Admin 2 学习笔记1
- 解决雷达图文字显示不全问题
- CentOS 7安装教程(图文详解)如下
- Linux服务器---关闭selinux
- @requirespermissions注解是什么意思_如何基于spring开发自定义注解实现对接口访问频次限制?...
- 路由器安置(Routing)
- [密码学基础][每个信息安全博士生应该知道的52件事][Bristol52]38.隐蔽信道和侧信道的区别
- python封装举例_Python+Pycharm—学习1—封装导入
- EOS Platform 7.2 安装
- 拓端tecdat|sas文本挖掘案例:如何使用SAS计算Word Mover的距离
- 阶段3 3.SpringMVC·_07.SSM整合案例_08.ssm整合之Spring整合MyBatis框架
- Tinker在sdk升级后无法成功打补丁包的问题
- 2018湘南学院计算机分数线,湘南学院录取分数线2021是多少分(附历年录取分数线)...
- 用C语言实现计算器功能
- java 数字信号_GitHub - Bazingaliu/JavaDsp: 数字信号处理(DSP)方面的Java封装,包含常用的一些处理方法,如滤波、信号变换等等。...
- 计算机网络中abc类地址,abc类ip地址-abc类ip地址和私有地址范围
- 在标准宽带光纤上实现量子加密
热门文章
- 除了祈福,我们还可以让消防更智能
- 任性动图---制作动图、录屏软件 可方便添加各种文字
- CentOS快速搭建服务器 超简单
- 为什么至少三个哨兵_部队大门为什么要立一块“哨兵神圣,不可侵犯”的牌子?_知道问答...
- bootstrap分页插件php,bootstrap paginator分页插件使用方法
- 中国人最常说的‘中国式英语’
- 微信开发 - 第三方网站接入微信登录、微信支付时,本地 redirect_uri 参数错误导致无法调试的解决方案(微信开放平台)完美解决每次都需要部署到线上测试,在本地使用本地 ip 就能轻松调试
- Mathtype部分数学符号不能显示,只能显示方框时的解决办法
- win10 anaconda用conda命令安装
- 关于地址栏收藏夹的图标