ABAP Json和对象的转换

se24新建类ZCL_JSON保存

点击修改,进入下图界面,点击红框。

复制粘贴下面代码

CLASS zcl_json DEFINITIONPUBLICCREATE PUBLIC .PUBLIC SECTION.
*"* public components of class ZCL_JSON
*"* do not include other source files here!!!TYPE-POOLS abap .CLASS cl_abap_tstmp DEFINITION LOAD .CLASS cx_sy_conversion_error DEFINITION LOAD .TYPES json TYPE string .TYPES:BEGIN OF name_mapping,abap TYPE abap_compname,json TYPE string,END OF name_mapping .TYPES:name_mappings    TYPE HASHED TABLE OF name_mapping WITH UNIQUE KEY abap .TYPES:ref_tab          TYPE STANDARD TABLE OF REF TO data WITH DEFAULT KEY .TYPES bool TYPE char1 .TYPES tribool TYPE char1 .TYPES pretty_name_mode TYPE char1 .CONSTANTS:BEGIN OF pretty_mode,none          TYPE char1  VALUE ``,low_case      TYPE char1  VALUE `L`,camel_case    TYPE char1  VALUE `X`,extended      TYPE char1  VALUE `Y`,user          TYPE char1  VALUE `U`,user_low_case TYPE char1  VALUE `C`,END OF  pretty_mode .CONSTANTS:BEGIN OF c_bool,true  TYPE bool  VALUE `X`,false TYPE bool  VALUE ``,END OF  c_bool .CONSTANTS:BEGIN OF c_tribool,true      TYPE tribool  VALUE c_bool-true,false     TYPE tribool  VALUE `-`,undefined TYPE tribool  VALUE ``,END OF  c_tribool .CONSTANTS mc_key_separator TYPE string VALUE `-`.       "#EC NOTEXTCONSTANTS version TYPE i VALUE 15.                      "#EC NOTEXTCLASS-DATA sv_white_space TYPE string READ-ONLY .CLASS-DATA mc_bool_types TYPE string READ-ONLY VALUE `\TYPE-POOL=ABAP\TYPE=ABAP_BOOL\TYPE=BOOLEAN\TYPE=BOOLE_D\TYPE=XFELD`. "#EC NOTEXT .CLASS-DATA mc_bool_3state TYPE string READ-ONLY VALUE `\TYPE=BOOLEAN`. "#EC NOTEXT .CLASS-DATA mc_json_type TYPE string READ-ONLY .CLASS-METHODS class_constructor .CLASS-METHODS string_to_xstringIMPORTING!in TYPE stringCHANGINGvalue(out) TYPE any .CLASS-METHODS xstring_to_stringIMPORTING!in TYPE anyRETURNINGvalue(out) TYPE string .CLASS-METHODS raw_to_stringIMPORTING!iv_xstring TYPE xstring!iv_encoding TYPE abap_encoding OPTIONALRETURNINGvalue(rv_string) TYPE string .CLASS-METHODS string_to_rawIMPORTING!iv_string TYPE string!iv_encoding TYPE abap_encoding OPTIONALRETURNINGvalue(rv_xstring) TYPE xstring .CLASS-METHODS deserializeIMPORTING!json TYPE json OPTIONAL!jsonx TYPE xstring OPTIONAL!pretty_name TYPE pretty_name_mode DEFAULT pretty_mode-none!assoc_arrays TYPE bool DEFAULT c_bool-false!assoc_arrays_opt TYPE bool DEFAULT c_bool-false!name_mappings TYPE name_mappings OPTIONAL!conversion_exits TYPE bool DEFAULT c_bool-falseCHANGING!data TYPE data .CLASS-METHODS serializeIMPORTING!data TYPE data!compress TYPE bool DEFAULT c_bool-false!name TYPE string OPTIONAL!pretty_name TYPE pretty_name_mode DEFAULT pretty_mode-none!type_descr TYPE REF TO cl_abap_typedescr OPTIONAL!assoc_arrays TYPE bool DEFAULT c_bool-false!ts_as_iso8601 TYPE bool DEFAULT c_bool-false!expand_includes TYPE bool DEFAULT c_bool-true!assoc_arrays_opt TYPE bool DEFAULT c_bool-false!numc_as_string TYPE bool DEFAULT c_bool-false!name_mappings TYPE name_mappings OPTIONAL!conversion_exits TYPE bool DEFAULT c_bool-falseRETURNINGvalue(r_json) TYPE json .METHODS deserialize_intIMPORTING!json TYPE json OPTIONAL!jsonx TYPE xstring OPTIONALCHANGING!data TYPE dataRAISINGcx_sy_move_cast_error .CLASS-METHODS generateIMPORTING!json TYPE json!pretty_name TYPE pretty_name_mode DEFAULT pretty_mode-none!name_mappings TYPE name_mappings OPTIONALRETURNINGvalue(rr_data) TYPE REF TO data .METHODS serialize_intIMPORTING!data TYPE data!name TYPE string OPTIONAL!type_descr TYPE REF TO cl_abap_typedescr OPTIONALRETURNINGvalue(r_json) TYPE json .METHODS generate_intIMPORTING!json TYPE jsonvalue(length) TYPE i OPTIONALRETURNINGvalue(rr_data) TYPE REF TO dataRAISINGcx_sy_move_cast_error .METHODS constructorIMPORTING!compress TYPE bool DEFAULT c_bool-false!pretty_name TYPE pretty_name_mode DEFAULT pretty_mode-none!assoc_arrays TYPE bool DEFAULT c_bool-false!ts_as_iso8601 TYPE bool DEFAULT c_bool-false!expand_includes TYPE bool DEFAULT c_bool-true!assoc_arrays_opt TYPE bool DEFAULT c_bool-false!strict_mode TYPE bool DEFAULT c_bool-false!numc_as_string TYPE bool DEFAULT c_bool-false!name_mappings TYPE name_mappings OPTIONAL!conversion_exits TYPE bool DEFAULT c_bool-false .CLASS-METHODS bool_to_triboolIMPORTING!iv_bool TYPE boolRETURNINGvalue(rv_tribool) TYPE tribool .CLASS-METHODS tribool_to_boolIMPORTING!iv_tribool TYPE triboolRETURNINGvalue(rv_bool) TYPE bool .PROTECTED SECTION.
*"* protected components of class ZCL_JSON
*"* do not include other source files here!!!TYPES:BEGIN OF t_s_symbol,header       TYPE string,name         TYPE string,type         TYPE REF TO cl_abap_datadescr,value        TYPE REF TO data,convexit_out TYPE string,convexit_in  TYPE string,compressable TYPE abap_bool,read_only    TYPE abap_bool,END OF t_s_symbol,t_t_symbol TYPE STANDARD TABLE OF t_s_symbol WITH DEFAULT KEY,BEGIN OF t_s_field_cache,name         TYPE string,type         TYPE REF TO cl_abap_datadescr,convexit_out TYPE string,convexit_in  TYPE string,value        TYPE REF TO data,END OF t_s_field_cache,t_t_field_cache  TYPE HASHED TABLE OF t_s_field_cache WITH UNIQUE KEY name,name_mappings_ex TYPE HASHED TABLE OF name_mapping WITH UNIQUE KEY json.DATA mv_compress TYPE bool .DATA mv_pretty_name TYPE pretty_name_mode .DATA mv_assoc_arrays TYPE bool .DATA mv_ts_as_iso8601 TYPE bool .DATA mt_name_mappings TYPE name_mappings .DATA mt_name_mappings_ex TYPE name_mappings_ex .DATA mv_expand_includes TYPE bool .DATA mv_assoc_arrays_opt TYPE bool .DATA mv_strict_mode TYPE bool .DATA mv_numc_as_string TYPE bool .DATA mv_conversion_exits TYPE bool .CLASS-DATA mc_name_symbols_map TYPE string VALUE ` _/_\_:_;_~_._,_-_+_=_>_<_|_(_)_[_]_{_}_@_+_*_?_!_&_$_#_%_^_'_§_` ##no_text.CLASS-METHODS unescapeIMPORTINGescaped          TYPE stringRETURNINGvalue(unescaped) TYPE string .CLASS-METHODS get_convexit_funcIMPORTINGelem_descr     TYPE REF TO cl_abap_elemdescrinput          TYPE abap_bool OPTIONALRETURNINGvalue(rv_func) TYPE string .METHODS dump_symbols FINALIMPORTINGit_symbols    TYPE t_t_symbolRETURNINGvalue(r_json) TYPE json .METHODS get_symbols FINALIMPORTINGtype_descr      TYPE REF TO cl_abap_typedescrdata            TYPE REF TO data OPTIONALobject          TYPE REF TO object OPTIONALinclude_aliases TYPE abap_bool DEFAULT abap_falseRETURNINGvalue(result)   TYPE t_t_symbol .METHODS get_fields FINALIMPORTINGtype_descr       TYPE REF TO cl_abap_typedescrdata             TYPE REF TO data OPTIONALobject           TYPE REF TO object OPTIONALRETURNINGvalue(rt_fields) TYPE t_t_field_cache .METHODS dump_intIMPORTINGdata          TYPE datatype_descr    TYPE REF TO cl_abap_typedescr OPTIONALconvexit      TYPE string OPTIONALRETURNINGvalue(r_json) TYPE json .METHODS is_compressableIMPORTINGtype_descr         TYPE REF TO cl_abap_typedescrname               TYPE csequenceRETURNINGvalue(rv_compress) TYPE abap_bool .METHODS restoreIMPORTINGjson              TYPE jsonlength            TYPE ivalue(type_descr) TYPE REF TO cl_abap_typedescr OPTIONALfield_cache       TYPE t_t_field_cache OPTIONALCHANGINGdata              TYPE data OPTIONALoffset            TYPE i DEFAULT 0RAISINGcx_sy_move_cast_error .METHODS restore_typeIMPORTINGjson              TYPE jsonlength            TYPE ivalue(type_descr) TYPE REF TO cl_abap_typedescr OPTIONALfield_cache       TYPE t_t_field_cache OPTIONALconvexit          TYPE string OPTIONALCHANGINGdata              TYPE data OPTIONALoffset            TYPE i DEFAULT 0RAISINGcx_sy_move_cast_error .METHODS dump_typeIMPORTINGdata          TYPE datatype_descr    TYPE REF TO cl_abap_elemdescrconvexit      TYPE stringRETURNINGvalue(r_json) TYPE json .METHODS pretty_name_exIMPORTINGin         TYPE csequenceRETURNINGvalue(out) TYPE string .METHODS generate_int_ex FINALIMPORTINGjson   TYPE jsonlength TYPE iCHANGINGdata   TYPE dataoffset TYPE i .METHODS pretty_nameIMPORTINGin         TYPE csequenceRETURNINGvalue(out) TYPE string .CLASS-METHODS escapeIMPORTINGin         TYPE anyRETURNINGvalue(out) TYPE string .CLASS-METHODS edm_datetime_to_tsIMPORTINGticks         TYPE stringoffset        TYPE string OPTIONALtypekind      TYPE abap_typekindRETURNINGvalue(r_data) TYPE string .PRIVATE SECTION.
*"* private components of class ZCL_JSON
*"* do not include other source files here!!!DATA mv_extended TYPE bool .CLASS-DATA mc_me_type TYPE string .CLASS-DATA mc_cov_error TYPE c .
ENDCLASS.CLASS ZCL_JSON IMPLEMENTATION.* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON=>BOOL_TO_TRIBOOL
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_BOOL                        TYPE        BOOL
* | [<-()] RV_TRIBOOL                     TYPE        TRIBOOL
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD bool_to_tribool.IF iv_bool EQ c_bool-true.rv_tribool = c_tribool-true.ELSEIF iv_bool EQ abap_undefined. " fall back for abap _boolrv_tribool = c_tribool-undefined.ELSE.rv_tribool = c_tribool-false.ENDIF.ENDMETHOD.                    "BOOL_TO_TRIBOOL* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON=>CLASS_CONSTRUCTOR
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD class_constructor.DATA: lo_bool_type_descr    TYPE REF TO cl_abap_typedescr,lo_tribool_type_descr TYPE REF TO cl_abap_typedescr,lo_json_type_descr    TYPE REF TO cl_abap_typedescr,lv_pos                LIKE sy-fdpos,lv_json_string        TYPE json.lo_bool_type_descr    = cl_abap_typedescr=>describe_by_data( c_bool-true ).lo_tribool_type_descr = cl_abap_typedescr=>describe_by_data( c_tribool-true ).lo_json_type_descr    = cl_abap_typedescr=>describe_by_data( lv_json_string ).CONCATENATE mc_bool_types lo_bool_type_descr->absolute_name lo_tribool_type_descr->absolute_name INTO mc_bool_types.CONCATENATE mc_bool_3state lo_tribool_type_descr->absolute_name INTO mc_bool_3state.CONCATENATE mc_json_type lo_json_type_descr->absolute_name INTO mc_json_type.FIND FIRST OCCURRENCE OF `\TYPE=` IN lo_json_type_descr->absolute_name MATCH OFFSET lv_pos.IF sy-subrc IS INITIAL.mc_me_type = lo_json_type_descr->absolute_name(lv_pos).ENDIF.sv_white_space = cl_abap_char_utilities=>get_simple_spaces_for_cur_cp( ).mc_cov_error = cl_abap_conv_in_ce=>uccp( '0000' ).ENDMETHOD.                    "CLASS_CONSTRUCTOR* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_JSON->CONSTRUCTOR
* +-------------------------------------------------------------------------------------------------+
* | [--->] COMPRESS                       TYPE        BOOL (default =C_BOOL-FALSE)
* | [--->] PRETTY_NAME                    TYPE        PRETTY_NAME_MODE (default =PRETTY_MODE-NONE)
* | [--->] ASSOC_ARRAYS                   TYPE        BOOL (default =C_BOOL-FALSE)
* | [--->] TS_AS_ISO8601                  TYPE        BOOL (default =C_BOOL-FALSE)
* | [--->] EXPAND_INCLUDES                TYPE        BOOL (default =C_BOOL-TRUE)
* | [--->] ASSOC_ARRAYS_OPT               TYPE        BOOL (default =C_BOOL-FALSE)
* | [--->] STRICT_MODE                    TYPE        BOOL (default =C_BOOL-FALSE)
* | [--->] NUMC_AS_STRING                 TYPE        BOOL (default =C_BOOL-FALSE)
* | [--->] NAME_MAPPINGS                  TYPE        NAME_MAPPINGS(optional)
* | [--->] CONVERSION_EXITS               TYPE        BOOL (default =C_BOOL-FALSE)
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD constructor.DATA: rtti TYPE REF TO cl_abap_classdescr,pair LIKE LINE OF name_mappings.mv_compress         = compress.mv_pretty_name      = pretty_name.mv_assoc_arrays     = assoc_arrays.mv_ts_as_iso8601    = ts_as_iso8601.mv_expand_includes  = expand_includes.mv_assoc_arrays_opt = assoc_arrays_opt.mv_strict_mode      = strict_mode.mv_numc_as_string   = numc_as_string.mv_conversion_exits = conversion_exits.LOOP AT name_mappings INTO pair.TRANSLATE pair-abap TO UPPER CASE.INSERT pair INTO TABLE mt_name_mappings.ENDLOOP." if it dumps here, you have passed ambiguous mapping to the API" please check your code for duplicates, pairs ABAP - JSON shall be uniqueINSERT LINES OF mt_name_mappings INTO TABLE mt_name_mappings_ex.IF mt_name_mappings IS NOT INITIAL.IF mv_pretty_name EQ pretty_mode-none.mv_pretty_name = pretty_mode-user.ELSEIF pretty_name EQ pretty_mode-low_case.mv_pretty_name = pretty_mode-user_low_case.ENDIF.ENDIF.rtti ?= cl_abap_classdescr=>describe_by_object_ref( me ).IF rtti->absolute_name NE mc_me_type.mv_extended = c_bool-true.ENDIF.ENDMETHOD.                    "CONSTRUCTOR* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON=>DESERIALIZE
* +-------------------------------------------------------------------------------------------------+
* | [--->] JSON                           TYPE        JSON(optional)
* | [--->] JSONX                          TYPE        XSTRING(optional)
* | [--->] PRETTY_NAME                    TYPE        PRETTY_NAME_MODE (default =PRETTY_MODE-NONE)
* | [--->] ASSOC_ARRAYS                   TYPE        BOOL (default =C_BOOL-FALSE)
* | [--->] ASSOC_ARRAYS_OPT               TYPE        BOOL (default =C_BOOL-FALSE)
* | [--->] NAME_MAPPINGS                  TYPE        NAME_MAPPINGS(optional)
* | [--->] CONVERSION_EXITS               TYPE        BOOL (default =C_BOOL-FALSE)
* | [<-->] DATA                           TYPE        DATA
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD deserialize.DATA: lo_json TYPE REF TO zcl_json." **********************************************************************" Usage examples and documentation can be found on SCN:" http://wiki.scn.sap.com/wiki/display/Snippets/One+more+ABAP+to+JSON+Serializer+and+Deserializer" **********************************************************************  "IF json IS NOT INITIAL OR jsonx IS NOT INITIAL.CREATE OBJECT lo_jsonEXPORTINGpretty_name      = pretty_namename_mappings    = name_mappingsassoc_arrays     = assoc_arraysconversion_exits = conversion_exitsassoc_arrays_opt = assoc_arrays_opt.TRY .lo_json->deserialize_int( EXPORTING json = json jsonx = jsonx CHANGING data = data ).CATCH cx_sy_move_cast_error.                    "#EC NO_HANDLERENDTRY.ENDIF.ENDMETHOD.                    "DESERIALIZE* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_JSON->DESERIALIZE_INT
* +-------------------------------------------------------------------------------------------------+
* | [--->] JSON                           TYPE        JSON(optional)
* | [--->] JSONX                          TYPE        XSTRING(optional)
* | [<-->] DATA                           TYPE        DATA
* | [!CX!] CX_SY_MOVE_CAST_ERROR
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD deserialize_int.DATA: length    TYPE i,offset    TYPE i,unescaped LIKE json." **********************************************************************" Usage examples and documentation can be found on SCN:" http://wiki.scn.sap.com/wiki/display/Snippets/One+more+ABAP+to+JSON+Serializer+and+Deserializer" **********************************************************************  "IF json IS NOT INITIAL OR jsonx IS NOT INITIAL.IF jsonx IS NOT INITIAL.unescaped = raw_to_string( jsonx ).ELSE.unescaped = json.ENDIF." skip leading BOM signslength = strlen( unescaped ).while_offset_not_cs `"{[` unescaped.unescaped = unescaped+offset.length = length - offset.restore_type( EXPORTING json = unescaped length = length CHANGING data = data ).ENDIF.ENDMETHOD.                    "DESERIALIZE_INT* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZCL_JSON->DUMP_INT
* +-------------------------------------------------------------------------------------------------+
* | [--->] DATA                           TYPE        DATA
* | [--->] TYPE_DESCR                     TYPE REF TO CL_ABAP_TYPEDESCR(optional)
* | [--->] CONVEXIT                       TYPE        STRING(optional)
* | [<-()] R_JSON                         TYPE        JSON
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD dump_int.DATA: lo_typedesc   TYPE REF TO cl_abap_typedescr,lo_elem_descr TYPE REF TO cl_abap_elemdescr,lo_classdesc  TYPE REF TO cl_abap_classdescr,lo_structdesc TYPE REF TO cl_abap_structdescr,lo_tabledescr TYPE REF TO cl_abap_tabledescr,lt_symbols    TYPE t_t_symbol,lt_keys       LIKE lt_symbols,lt_properties TYPE STANDARD TABLE OF string,lt_fields     TYPE STANDARD TABLE OF string,lo_obj_ref    TYPE REF TO object,lo_data_ref   TYPE REF TO data,ls_skip_key   TYPE LINE OF abap_keydescr_tab,lv_array_opt  TYPE abap_bool,lv_prop_name  TYPE string,lv_keyval     TYPE string,lv_itemval    TYPE string.FIELD-SYMBOLS: <line>   TYPE any,<value>  TYPE any,<data>   TYPE data,<key>    TYPE LINE OF abap_keydescr_tab,<symbol> LIKE LINE OF lt_symbols,<table>  TYPE ANY TABLE." we need here macro instead of method calls because of the performance reasons." based on SAT measurements.CASE type_descr->kind.WHEN cl_abap_typedescr=>kind_ref.IF data IS INITIAL.r_json = `null`.                                  "#EC NOTEXTELSEIF type_descr->type_kind EQ cl_abap_typedescr=>typekind_dref.lo_data_ref ?= data.lo_typedesc = cl_abap_typedescr=>describe_by_data_ref( lo_data_ref ).ASSIGN lo_data_ref->* TO <data>.r_json = dump_int( data = <data> type_descr = lo_typedesc ).ELSE.lo_obj_ref ?= data.lo_classdesc ?= cl_abap_typedescr=>describe_by_object_ref( lo_obj_ref ).lt_symbols = get_symbols( type_descr = lo_classdesc object = lo_obj_ref ).r_json = dump_symbols( lt_symbols ).ENDIF.WHEN cl_abap_typedescr=>kind_elem.lo_elem_descr ?= type_descr.dump_type data lo_elem_descr r_json convexit.WHEN cl_abap_typedescr=>kind_struct.lo_structdesc ?= type_descr.GET REFERENCE OF data INTO lo_data_ref.lt_symbols = get_symbols( type_descr = lo_structdesc data = lo_data_ref ).r_json = dump_symbols( lt_symbols ).WHEN cl_abap_typedescr=>kind_table.lo_tabledescr ?= type_descr.lo_typedesc = lo_tabledescr->get_table_line_type( ).ASSIGN data TO <table>." optimization for structured tablesIF lo_typedesc->kind EQ cl_abap_typedescr=>kind_struct.lo_structdesc ?= lo_typedesc.CREATE DATA lo_data_ref LIKE LINE OF <table>.ASSIGN lo_data_ref->* TO <line>.lt_symbols = get_symbols( type_descr = lo_structdesc data = lo_data_ref )." here we have differentiation of output of simple table to JSON array" and sorted or hashed table with unique key into JSON associative arrayIF lo_tabledescr->has_unique_key IS NOT INITIAL AND mv_assoc_arrays IS NOT INITIAL.IF lo_tabledescr->key_defkind EQ lo_tabledescr->keydefkind_user.LOOP AT lo_tabledescr->key ASSIGNING <key>.READ TABLE lt_symbols WITH KEY name = <key>-name ASSIGNING <symbol>.APPEND <symbol> TO lt_keys.ENDLOOP.ENDIF.IF lines( lo_tabledescr->key ) EQ 1.READ TABLE lo_tabledescr->key INDEX 1 INTO ls_skip_key.DELETE lt_symbols WHERE name EQ ls_skip_key-name." remove object wrapping for simple name-value tablesIF mv_assoc_arrays_opt EQ abap_true AND lines( lt_symbols ) EQ 1.lv_array_opt = abap_true.ENDIF.ENDIF.LOOP AT <table> INTO <line>.CLEAR: lt_fields, lv_prop_name.LOOP AT lt_symbols ASSIGNING <symbol>.ASSIGN <symbol>-value->* TO <value>.IF mv_compress IS INITIAL OR <value> IS NOT INITIAL OR <symbol>-compressable EQ abap_false.IF <symbol>-type->kind EQ cl_abap_typedescr=>kind_elem.lo_elem_descr ?= <symbol>-type.dump_type <value> lo_elem_descr lv_itemval <symbol>-convexit_out.ELSE.lv_itemval = dump_int( data = <value> type_descr = <symbol>-type convexit = <symbol>-convexit_out ).ENDIF.IF lv_array_opt EQ abap_false.CONCATENATE <symbol>-header lv_itemval INTO lv_itemval.ENDIF.APPEND lv_itemval TO lt_fields.ENDIF.ENDLOOP.IF lo_tabledescr->key_defkind EQ lo_tabledescr->keydefkind_user.LOOP AT lt_keys ASSIGNING <symbol>.ASSIGN <symbol>-value->* TO <value>.lv_keyval = <value>.CONDENSE lv_keyval.IF lv_prop_name IS NOT INITIAL.CONCATENATE lv_prop_name mc_key_separator lv_keyval INTO lv_prop_name.ELSE.lv_prop_name = lv_keyval.ENDIF.ENDLOOP.ELSE.LOOP AT lt_symbols ASSIGNING <symbol>.ASSIGN <symbol>-value->* TO <value>.lv_keyval = <value>.CONDENSE lv_keyval.IF lv_prop_name IS NOT INITIAL.CONCATENATE lv_prop_name mc_key_separator lv_keyval INTO lv_prop_name.ELSE.lv_prop_name = lv_keyval.ENDIF.ENDLOOP.ENDIF.CONCATENATE LINES OF lt_fields INTO lv_itemval SEPARATED BY `,`.IF lv_array_opt EQ abap_false.CONCATENATE `"` lv_prop_name `":{` lv_itemval `}` INTO lv_itemval.ELSE.CONCATENATE `"` lv_prop_name `":` lv_itemval `` INTO lv_itemval.ENDIF.APPEND lv_itemval TO lt_properties.ENDLOOP.CONCATENATE LINES OF lt_properties INTO r_json SEPARATED BY `,`.CONCATENATE `{` r_json `}` INTO r_json.ELSE.LOOP AT <table> INTO <line>.CLEAR lt_fields.LOOP AT lt_symbols ASSIGNING <symbol>.ASSIGN <symbol>-value->* TO <value>.IF mv_compress IS INITIAL OR <value> IS NOT INITIAL OR <symbol>-compressable EQ abap_false.IF <symbol>-type->kind EQ cl_abap_typedescr=>kind_elem.lo_elem_descr ?= <symbol>-type.dump_type <value> lo_elem_descr lv_itemval <symbol>-convexit_out.ELSE.lv_itemval = dump_int( data = <value> type_descr = <symbol>-type convexit = <symbol>-convexit_out ).ENDIF.CONCATENATE <symbol>-header lv_itemval INTO lv_itemval.APPEND lv_itemval TO lt_fields.ENDIF.ENDLOOP.CONCATENATE LINES OF lt_fields INTO lv_itemval SEPARATED BY `,`.CONCATENATE `{` lv_itemval `}` INTO lv_itemval.APPEND lv_itemval TO lt_properties.ENDLOOP.CONCATENATE LINES OF lt_properties INTO r_json SEPARATED BY `,`.CONCATENATE `[` r_json `]` INTO r_json.ENDIF.ELSE.LOOP AT <table> ASSIGNING <value>.lv_itemval = dump_int( data = <value> type_descr = lo_typedesc ).APPEND lv_itemval TO lt_properties.ENDLOOP.CONCATENATE LINES OF lt_properties INTO r_json SEPARATED BY `,`.CONCATENATE `[` r_json `]` INTO r_json.ENDIF.ENDCASE.ENDMETHOD.                    "DUMP_INT* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZCL_JSON->DUMP_SYMBOLS
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_SYMBOLS                     TYPE        T_T_SYMBOL
* | [<-()] R_JSON                         TYPE        JSON
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD dump_symbols.DATA: lv_properties      TYPE STANDARD TABLE OF string,lv_itemval         TYPE string.FIELD-SYMBOLS: <value>   TYPE any,<symbol>  LIKE LINE OF it_symbols.LOOP AT it_symbols ASSIGNING <symbol>.ASSIGN <symbol>-value->* TO <value>.IF mv_compress IS INITIAL OR <value> IS NOT INITIAL OR <symbol>-compressable EQ abap_false.lv_itemval = dump_int( data = <value> type_descr = <symbol>-type convexit = <symbol>-convexit_out ).CONCATENATE <symbol>-header lv_itemval INTO lv_itemval.APPEND lv_itemval TO lv_properties.ENDIF.ENDLOOP.CONCATENATE LINES OF lv_properties INTO r_json SEPARATED BY `,`.CONCATENATE `{` r_json `}` INTO r_json.ENDMETHOD.                    "DUMP_SYMBOLS* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZCL_JSON->DUMP_TYPE
* +-------------------------------------------------------------------------------------------------+
* | [--->] DATA                           TYPE        DATA
* | [--->] TYPE_DESCR                     TYPE REF TO CL_ABAP_ELEMDESCR
* | [--->] CONVEXIT                       TYPE        STRING
* | [<-()] R_JSON                         TYPE        JSON
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD dump_type.CONSTANTS: lc_typekind_utclong TYPE abap_typekind VALUE 'p', " CL_ABAP_TYPEDESCR=>TYPEKIND_UTCLONG -> 'p' only from 7.60lc_typekind_int8    TYPE abap_typekind VALUE '8'.  " TYPEKIND_INT8 -> '8' only from 7.40IF convexit IS NOT INITIAL AND data IS NOT INITIAL.TRY.CALL FUNCTION convexitEXPORTINGinput  = dataIMPORTINGoutput = r_jsonEXCEPTIONSOTHERS = 1.IF sy-subrc IS INITIAL.CONCATENATE `"` r_json `"` INTO r_json.ENDIF.CATCH cx_root.                                  "#EC NO_HANDLERENDTRY.ELSE.CASE type_descr->type_kind.WHEN cl_abap_typedescr=>typekind_float OR cl_abap_typedescr=>typekind_int OR cl_abap_typedescr=>typekind_int1 ORcl_abap_typedescr=>typekind_int2 OR cl_abap_typedescr=>typekind_packed OR lc_typekind_utclong OR lc_typekind_int8.IF mv_ts_as_iso8601 EQ c_bool-true AND( type_descr->type_kind EQ lc_typekind_utclong OR( type_descr->type_kind EQ cl_abap_typedescr=>typekind_packed AND type_descr->absolute_name CP `\TYPE=TIMESTAMP*` ) ).IF data IS INITIAL.r_json = `""`.ELSE.r_json = data.IF type_descr->absolute_name EQ `\TYPE=TIMESTAMP`.CONCATENATE `"` r_json(4) `-` r_json+4(2) `-` r_json+6(2) `T` r_json+8(2) `:` r_json+10(2) `:` r_json+12(2) `.0000000Z"`  INTO r_json.ELSEIF type_descr->absolute_name EQ `\TYPE=TIMESTAMPL`.CONCATENATE `"` r_json(4) `-` r_json+4(2) `-` r_json+6(2) `T` r_json+8(2) `:` r_json+10(2) `:` r_json+12(2) `.` r_json+15(7) `Z"`  INTO r_json.ENDIF.ENDIF.ELSEIF data IS INITIAL.r_json = `0`.ELSE.r_json = data.IF data LT 0.IF type_descr->type_kind <> cl_abap_typedescr=>typekind_float. "float: sign is already at the beginningSHIFT r_json RIGHT CIRCULAR.ENDIF.ELSE.CONDENSE r_json.ENDIF.ENDIF.WHEN cl_abap_typedescr=>typekind_num.IF mv_numc_as_string EQ abap_true.IF data IS INITIAL.r_json = `""`.ELSE.CONCATENATE `"` data `"` INTO r_json.ENDIF.ELSE.r_json = data.SHIFT r_json LEFT DELETING LEADING ` 0`.IF r_json IS INITIAL.r_json = `0`.ENDIF.ENDIF.WHEN cl_abap_typedescr=>typekind_string OR cl_abap_typedescr=>typekind_csequence OR cl_abap_typedescr=>typekind_clike.IF data IS INITIAL.r_json = `""`.ELSEIF type_descr->absolute_name EQ mc_json_type.r_json = data.ELSE.r_json = escape( data ).CONCATENATE `"` r_json `"` INTO r_json.ENDIF.WHEN cl_abap_typedescr=>typekind_xstring OR cl_abap_typedescr=>typekind_hex.IF data IS INITIAL.r_json = `""`.ELSE.r_json = xstring_to_string( data ).r_json = escape( r_json ).CONCATENATE `"` r_json `"` INTO r_json.ENDIF.WHEN cl_abap_typedescr=>typekind_char.IF type_descr->output_length EQ 1 AND mc_bool_types CS type_descr->absolute_name.IF data EQ c_bool-true.r_json = `true`.                              "#EC NOTEXTELSEIF mc_bool_3state CS type_descr->absolute_name AND data IS INITIAL.r_json = `null`.                              "#EC NOTEXTELSE.r_json = `false`.                             "#EC NOTEXTENDIF.ELSE.r_json = escape( data ).CONCATENATE `"` r_json `"` INTO r_json.ENDIF.WHEN cl_abap_typedescr=>typekind_date.CONCATENATE `"` data(4) `-` data+4(2) `-` data+6(2) `"` INTO r_json.WHEN cl_abap_typedescr=>typekind_time.CONCATENATE `"` data(2) `:` data+2(2) `:` data+4(2) `"` INTO r_json.WHEN 'k'. " cl_abap_typedescr=>typekind_enumr_json = data.CONCATENATE `"` r_json `"` INTO r_json.WHEN OTHERS.IF data IS INITIAL.r_json = `null`.                                "#EC NOTEXTELSE.r_json = data.ENDIF.ENDCASE.ENDIF.ENDMETHOD.                    "DUMP_TYPE* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Protected Method ZCL_JSON=>EDM_DATETIME_TO_TS
* +-------------------------------------------------------------------------------------------------+
* | [--->] TICKS                          TYPE        STRING
* | [--->] OFFSET                         TYPE        STRING(optional)
* | [--->] TYPEKIND                       TYPE        ABAP_TYPEKIND
* | [<-()] R_DATA                         TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD edm_datetime_to_ts.CONSTANTS: lc_epochs TYPE string VALUE `19700101000000`.DATA: lv_ticks      TYPE p,lv_seconds    TYPE p,lv_subsec     TYPE p,lv_timestamps TYPE string,lv_timestamp  TYPE timestampl VALUE `19700101000000.0000000`.lv_ticks     = ticks.lv_seconds   = lv_ticks / 1000. " in secondslv_subsec    = lv_ticks MOD 1000. " in subsecIF lv_subsec GT 0.lv_timestamps = lv_subsec.CONCATENATE lc_epochs `.` lv_timestamps INTO lv_timestamps.lv_timestamp = lv_timestamps.ENDIF.lv_timestamp = cl_abap_tstmp=>add( tstmp = lv_timestamp secs = lv_seconds ).IF offset IS NOT INITIAL.lv_ticks = offset+1.lv_ticks = lv_ticks * 60. "offset is in minutesIF offset(1) = '+'.lv_timestamp = cl_abap_tstmp=>subtractsecs( tstmp = lv_timestamp secs = lv_ticks ).ELSE.lv_timestamp = cl_abap_tstmp=>add( tstmp = lv_timestamp secs = lv_ticks ).ENDIF.ENDIF.CASE typekind.WHEN cl_abap_typedescr=>typekind_time.r_data = lv_timestamp.r_data = r_data+8(6).WHEN cl_abap_typedescr=>typekind_date.r_data = lv_timestamp.r_data = r_data(8).WHEN cl_abap_typedescr=>typekind_packed.r_data = lv_timestamp.ENDCASE.ENDMETHOD.                    "EDM_DATETIME_TO_TS* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Protected Method ZCL_JSON=>ESCAPE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IN                             TYPE        ANY
* | [<-()] OUT                            TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD escape.out = in.REPLACE ALL OCCURRENCES OF `\` IN out WITH `\\`.REPLACE ALL OCCURRENCES OF `"` IN out WITH `\"`.ENDMETHOD.                    "ESCAPE* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON=>GENERATE
* +-------------------------------------------------------------------------------------------------+
* | [--->] JSON                           TYPE        JSON
* | [--->] PRETTY_NAME                    TYPE        PRETTY_NAME_MODE (default =PRETTY_MODE-NONE)
* | [--->] NAME_MAPPINGS                  TYPE        NAME_MAPPINGS(optional)
* | [<-()] RR_DATA                        TYPE REF TO DATA
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD generate.DATA: lo_json TYPE REF TO zcl_json,offset  TYPE i,length  TYPE i,lv_json LIKE json." skip leading BOM signslength = strlen( json ).while_offset_not_cs `"{[` json.lv_json = json+offset.length  = length - offset.CREATE OBJECT lo_jsonEXPORTINGpretty_name      = pretty_namename_mappings    = name_mappingsassoc_arrays     = c_bool-trueassoc_arrays_opt = c_bool-true.TRY .rr_data = lo_json->generate_int( json = lv_json length = length ).CATCH cx_sy_move_cast_error.                      "#EC NO_HANDLERENDTRY.ENDMETHOD.                    "GENERATE* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_JSON->GENERATE_INT
* +-------------------------------------------------------------------------------------------------+
* | [--->] JSON                           TYPE        JSON
* | [--->] LENGTH                         TYPE        I(optional)
* | [<-()] RR_DATA                        TYPE REF TO DATA
* | [!CX!] CX_SY_MOVE_CAST_ERROR
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD generate_int.TYPES: BEGIN OF ts_field,name  TYPE string,value TYPE json,END OF ts_field.DATA: offset TYPE i.DATA: lt_json      TYPE STANDARD TABLE OF json WITH DEFAULT KEY,lv_comp_name TYPE abap_compname,lt_fields    TYPE SORTED TABLE OF ts_field WITH UNIQUE KEY name,lo_type      TYPE REF TO cl_abap_datadescr,lt_comp      TYPE abap_component_tab,lt_names     TYPE HASHED TABLE OF string WITH UNIQUE KEY table_line,cache        LIKE LINE OF mt_name_mappings_ex,ls_comp      LIKE LINE OF lt_comp.FIELD-SYMBOLS: <data>   TYPE any,<struct> TYPE any,<json>   LIKE LINE OF lt_json,<field>  LIKE LINE OF lt_fields,<table>  TYPE STANDARD TABLE,<cache>  LIKE LINE OF mt_name_mappings_ex.IF length IS NOT SUPPLIED.length = strlen( json ).ENDIF.eat_white.CASE json+offset(1).WHEN `{`."result must be a structurerestore_type( EXPORTING json = json length = length CHANGING  data = lt_fields ).IF lt_fields IS NOT INITIAL.ls_comp-type = cl_abap_refdescr=>get_ref_to_data( ).LOOP AT lt_fields ASSIGNING <field>.READ TABLE mt_name_mappings_ex WITH TABLE KEY json = <field>-name ASSIGNING <cache>.IF sy-subrc IS INITIAL.ls_comp-name = <cache>-abap.ELSE.cache-json = ls_comp-name = <field>-name." remove characters not allowed in component namesTRANSLATE ls_comp-name USING ` _/_\_:_~_._-_=_>_<_(_)_@_+_*_?_&_$_#_%_^_`.IF mv_pretty_name EQ pretty_mode-camel_case OR mv_pretty_name EQ pretty_mode-extended.REPLACE ALL OCCURRENCES OF REGEX `([a-z])([A-Z])` IN ls_comp-name WITH `$1_$2`. "#EC NOTEXTENDIF.TRANSLATE ls_comp-name TO UPPER CASE.cache-abap = ls_comp-name = lv_comp_name = ls_comp-name. " truncate by allowed field name lengthINSERT cache INTO TABLE mt_name_mappings_ex.ENDIF.INSERT ls_comp-name INTO TABLE lt_names.IF sy-subrc IS INITIAL.APPEND ls_comp TO lt_comp.ELSE.DELETE lt_fields.ENDIF.ENDLOOP.TRY.lo_type = cl_abap_structdescr=>create( p_components = lt_comp p_strict = c_bool-false ).CREATE DATA rr_data TYPE HANDLE lo_type.ASSIGN rr_data->* TO <struct>.LOOP AT lt_fields ASSIGNING <field>.ASSIGN COMPONENT sy-tabix OF STRUCTURE <struct> TO <data>.<data> = generate_int( <field>-value ).ENDLOOP.CATCH cx_sy_create_data_error cx_sy_struct_creation. "#EC NO_HANDLERENDTRY.ENDIF.RETURN.WHEN `[`."result must be a table of refrestore_type( EXPORTING json = json length = length CHANGING  data = lt_json ).CREATE DATA rr_data TYPE TABLE OF REF TO data.ASSIGN rr_data->* TO <table>.LOOP AT lt_json ASSIGNING <json>.APPEND INITIAL LINE TO <table> ASSIGNING <data>.<data> = generate_int( <json> ).ENDLOOP.RETURN.WHEN `"`."stringCREATE DATA rr_data TYPE string.WHEN `-` OR `0` OR `1` OR `2` OR `3` OR `4` OR `5` OR `6` OR `7` OR `8` OR `9`. " numberIF json+offset CS '.'.CREATE DATA rr_data TYPE f.ELSEIF length GT 9.CREATE DATA rr_data TYPE p.ELSE.CREATE DATA rr_data TYPE i.ENDIF.WHEN OTHERS.IF json+offset EQ `true` OR json+offset EQ `false`. "#EC NOTEXTCREATE DATA rr_data TYPE abap_bool.ENDIF.ENDCASE.IF rr_data IS BOUND.ASSIGN rr_data->* TO <data>.restore_type( EXPORTING json = json length = length CHANGING  data = <data> ).ENDIF.ENDMETHOD.                    "GENERATE_INT* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZCL_JSON->GENERATE_INT_EX
* +-------------------------------------------------------------------------------------------------+
* | [--->] JSON                           TYPE        JSON
* | [--->] LENGTH                         TYPE        I
* | [<-->] DATA                           TYPE        DATA
* | [<-->] OFFSET                         TYPE        I
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD generate_int_ex.DATA: lv_assoc_arrays     LIKE mv_assoc_arrays,lv_assoc_arrays_opt LIKE mv_assoc_arrays_opt,lv_mark             LIKE offset,lv_match            LIKE lv_mark,lv_json             TYPE zcl_json=>json.lv_mark = offset.restore_type( EXPORTING json = json length = length CHANGING offset = offset ).lv_match = offset - lv_mark.lv_json = json+lv_mark(lv_match).lv_assoc_arrays     = mv_assoc_arrays.lv_assoc_arrays_opt = mv_assoc_arrays_opt.mv_assoc_arrays     = abap_true.mv_assoc_arrays_opt = abap_true.data = generate_int( lv_json ).mv_assoc_arrays = lv_assoc_arrays.mv_assoc_arrays_opt = lv_assoc_arrays_opt.ENDMETHOD.                    "GENERATE_INT_EX* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Protected Method ZCL_JSON=>GET_CONVEXIT_FUNC
* +-------------------------------------------------------------------------------------------------+
* | [--->] ELEM_DESCR                     TYPE REF TO CL_ABAP_ELEMDESCR
* | [--->] INPUT                          TYPE        ABAP_BOOL(optional)
* | [<-()] RV_FUNC                        TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD get_convexit_func.DATA: ls_dfies     TYPE dfies.elem_descr->get_ddic_field(RECEIVINGp_flddescr   = ls_dfies    " Field DescriptionEXCEPTIONSnot_found    = 1no_ddic_type = 2OTHERS       = 3).IF sy-subrc IS INITIAL AND ls_dfies-convexit IS NOT INITIAL.IF input EQ abap_true.CONCATENATE 'CONVERSION_EXIT_' ls_dfies-convexit '_INPUT' INTO rv_func.ELSE.CONCATENATE 'CONVERSION_EXIT_' ls_dfies-convexit '_OUTPUT' INTO rv_func.ENDIF.ENDIF.ENDMETHOD.                    "GET_CONVEXIT_FUNC* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZCL_JSON->GET_FIELDS
* +-------------------------------------------------------------------------------------------------+
* | [--->] TYPE_DESCR                     TYPE REF TO CL_ABAP_TYPEDESCR
* | [--->] DATA                           TYPE REF TO DATA(optional)
* | [--->] OBJECT                         TYPE REF TO OBJECT(optional)
* | [<-()] RT_FIELDS                      TYPE        T_T_FIELD_CACHE
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD get_fields.DATA: lt_symbols  TYPE t_t_symbol,lv_name     TYPE char128,ls_field    LIKE LINE OF rt_fields.FIELD-SYMBOLS: <sym>   LIKE LINE OF lt_symbols,<cache> LIKE LINE OF mt_name_mappings.lt_symbols = get_symbols( type_descr = type_descr data = data object = object include_aliases = abap_true ).LOOP AT lt_symbols ASSIGNING <sym> WHERE read_only EQ abap_false.MOVE-CORRESPONDING <sym> TO ls_field." insert as UPPER CASEINSERT ls_field INTO TABLE rt_fields." insert as lower case
*      TRANSLATE ls_field-name TO LOWER CASE.
*      INSERT ls_field INTO TABLE rt_fields." as pretty printedIF mv_pretty_name NE pretty_mode-none AND mv_pretty_name NE pretty_mode-low_case.format_name <sym>-name mv_pretty_name ls_field-name.INSERT ls_field INTO TABLE rt_fields." let us check for not well formed canelCase to be compatible with old logiclv_name = ls_field-name.TRANSLATE lv_name(1) TO UPPER CASE.ls_field-name = lv_name.INSERT ls_field INTO TABLE rt_fields.ENDIF.ENDLOOP.ENDMETHOD.                    "GET_FIELDS* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZCL_JSON->GET_SYMBOLS
* +-------------------------------------------------------------------------------------------------+
* | [--->] TYPE_DESCR                     TYPE REF TO CL_ABAP_TYPEDESCR
* | [--->] DATA                           TYPE REF TO DATA(optional)
* | [--->] OBJECT                         TYPE REF TO OBJECT(optional)
* | [--->] INCLUDE_ALIASES                TYPE        ABAP_BOOL (default =ABAP_FALSE)
* | [<-()] RESULT                         TYPE        T_T_SYMBOL
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD get_symbols.DATA: comp_tab     TYPE cl_abap_structdescr=>component_table,symb_tab     LIKE result,symb         LIKE LINE OF symb_tab,elem_descr   TYPE REF TO cl_abap_elemdescr,class_descr  TYPE REF TO cl_abap_classdescr,struct_descr TYPE REF TO cl_abap_structdescr.FIELD-SYMBOLS: <comp>  LIKE LINE OF comp_tab,<attr>  LIKE LINE OF cl_abap_objectdescr=>attributes,<cache> LIKE LINE OF mt_name_mappings,<field> TYPE any.IF type_descr->kind EQ cl_abap_typedescr=>kind_struct.struct_descr ?= type_descr.comp_tab = struct_descr->get_components( ).LOOP AT comp_tab ASSIGNING <comp>.IF <comp>-name IS NOT INITIAL AND( <comp>-as_include EQ abap_false OR include_aliases EQ abap_true OR mv_expand_includes EQ abap_false ).symb-name = <comp>-name.symb-type = <comp>-type.IF data IS BOUND.IF mv_conversion_exits EQ abap_true AND symb-type->kind EQ cl_abap_typedescr=>kind_elem.elem_descr ?= symb-type.symb-convexit_in = get_convexit_func( elem_descr = elem_descr input = abap_true ).symb-convexit_out = get_convexit_func( elem_descr = elem_descr input = abap_false ).ENDIF.is_compressable symb-type symb-name symb-compressable.ASSIGN data->(symb-name) TO <field>.GET REFERENCE OF <field> INTO symb-value.format_name symb-name mv_pretty_name symb-header.CONCATENATE `"` symb-header  `":` INTO symb-header.ENDIF.APPEND symb TO result.ENDIF.IF <comp>-as_include EQ abap_true AND mv_expand_includes EQ abap_true.struct_descr ?= <comp>-type.symb_tab = get_symbols( type_descr = struct_descr include_aliases = include_aliases ).LOOP AT symb_tab INTO symb.CONCATENATE symb-name <comp>-suffix INTO symb-name.IF data IS BOUND.IF mv_conversion_exits EQ abap_true AND symb-type->kind EQ cl_abap_typedescr=>kind_elem.elem_descr ?= symb-type.symb-convexit_in = get_convexit_func( elem_descr = elem_descr input = abap_true ).symb-convexit_out = get_convexit_func( elem_descr = elem_descr input = abap_false ).ENDIF.is_compressable symb-type symb-name symb-compressable.ASSIGN data->(symb-name) TO <field>.GET REFERENCE OF <field> INTO symb-value.format_name symb-name mv_pretty_name symb-header.CONCATENATE `"` symb-header  `":` INTO symb-header.ENDIF.APPEND symb TO result.ENDLOOP.ENDIF.ENDLOOP.ELSEIF type_descr->type_kind EQ cl_abap_typedescr=>typekind_class.class_descr ?= type_descr.LOOP AT class_descr->attributes ASSIGNING <attr> WHERE is_constant IS INITIAL AND alias_for IS INITIAL AND( is_interface IS INITIAL OR type_kind NE cl_abap_typedescr=>typekind_oref ).ASSIGN object->(<attr>-name) TO <field>.CHECK sy-subrc IS INITIAL. " we can only assign to public attributessymb-name = <attr>-name.symb-read_only = <attr>-is_read_only.symb-type = class_descr->get_attribute_type( <attr>-name ).IF mv_conversion_exits EQ abap_true AND symb-type->kind EQ cl_abap_typedescr=>kind_elem.elem_descr ?= symb-type.symb-convexit_in = get_convexit_func( elem_descr = elem_descr input = abap_true ).symb-convexit_out = get_convexit_func( elem_descr = elem_descr input = abap_false ).ENDIF.is_compressable symb-type symb-name symb-compressable.GET REFERENCE OF <field> INTO symb-value.format_name symb-name mv_pretty_name symb-header.CONCATENATE `"` symb-header  `":` INTO symb-header.APPEND symb TO result.ENDLOOP.ENDIF.ENDMETHOD.                    "GET_SYMBOLS* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZCL_JSON->IS_COMPRESSABLE
* +-------------------------------------------------------------------------------------------------+
* | [--->] TYPE_DESCR                     TYPE REF TO CL_ABAP_TYPEDESCR
* | [--->] NAME                           TYPE        CSEQUENCE
* | [<-()] RV_COMPRESS                    TYPE        ABAP_BOOL
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD is_compressable.rv_compress = abap_true.ENDMETHOD.                    "IS_COMPRESSABLE* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZCL_JSON->PRETTY_NAME
* +-------------------------------------------------------------------------------------------------+
* | [--->] IN                             TYPE        CSEQUENCE
* | [<-()] OUT                            TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD pretty_name.DATA: tokens TYPE TABLE OF char128,cache  LIKE LINE OF mt_name_mappings.FIELD-SYMBOLS: <token> LIKE LINE OF tokens,<cache> LIKE LINE OF mt_name_mappings.READ TABLE mt_name_mappings WITH TABLE KEY abap = in ASSIGNING <cache>.IF sy-subrc IS INITIAL.out = <cache>-json.ELSE.out = in.REPLACE ALL OCCURRENCES OF `__` IN out WITH `*`.TRANSLATE out TO LOWER CASE.TRANSLATE out USING `/_:_~_`.SPLIT out AT `_` INTO TABLE tokens.LOOP AT tokens ASSIGNING <token> FROM 2.TRANSLATE <token>(1) TO UPPER CASE.ENDLOOP.CONCATENATE LINES OF tokens INTO out.REPLACE ALL OCCURRENCES OF `*` IN out WITH `_`.cache-abap  = in.cache-json = out.INSERT cache INTO TABLE mt_name_mappings.INSERT cache INTO TABLE mt_name_mappings_ex.ENDIF.ENDMETHOD.                    "PRETTY_NAME* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZCL_JSON->PRETTY_NAME_EX
* +-------------------------------------------------------------------------------------------------+
* | [--->] IN                             TYPE        CSEQUENCE
* | [<-()] OUT                            TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD pretty_name_ex.DATA: tokens    TYPE TABLE OF char128,cache     LIKE LINE OF mt_name_mappings.FIELD-SYMBOLS: <token>      LIKE LINE OF tokens,<cache>      LIKE LINE OF mt_name_mappings.READ TABLE mt_name_mappings WITH TABLE KEY abap = in ASSIGNING <cache>.IF sy-subrc IS INITIAL.out = <cache>-json.ELSE.out = in.TRANSLATE out TO LOWER CASE.TRANSLATE out USING `/_:_~_`.REPLACE ALL OCCURRENCES OF `__e__` IN out WITH `!`.REPLACE ALL OCCURRENCES OF `__n__` IN out WITH `#`.REPLACE ALL OCCURRENCES OF `__d__` IN out WITH `$`.REPLACE ALL OCCURRENCES OF `__p__` IN out WITH `%`.REPLACE ALL OCCURRENCES OF `__m__` IN out WITH `&`.REPLACE ALL OCCURRENCES OF `__s__` IN out WITH `*`.REPLACE ALL OCCURRENCES OF `__h__` IN out WITH `-`.REPLACE ALL OCCURRENCES OF `__t__` IN out WITH `~`.REPLACE ALL OCCURRENCES OF `__l__` IN out WITH `/`.REPLACE ALL OCCURRENCES OF `__c__` IN out WITH `:`.REPLACE ALL OCCURRENCES OF `__v__` IN out WITH `|`.REPLACE ALL OCCURRENCES OF `__a__` IN out WITH `@`.REPLACE ALL OCCURRENCES OF `__o__` IN out WITH `.`.REPLACE ALL OCCURRENCES OF `___`   IN out WITH `.`.REPLACE ALL OCCURRENCES OF `__` IN out WITH `"`.SPLIT out AT `_` INTO TABLE tokens.LOOP AT tokens ASSIGNING <token> FROM 2.TRANSLATE <token>(1) TO UPPER CASE.ENDLOOP.CONCATENATE LINES OF tokens INTO out.REPLACE ALL OCCURRENCES OF `"` IN out WITH `_`.cache-abap  = in.cache-json = out.INSERT cache INTO TABLE mt_name_mappings.INSERT cache INTO TABLE mt_name_mappings_ex.ENDIF.ENDMETHOD.                    "PRETTY_NAME_EX* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON=>RAW_TO_STRING
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_XSTRING                     TYPE        XSTRING
* | [--->] IV_ENCODING                    TYPE        ABAP_ENCODING(optional)
* | [<-()] RV_STRING                      TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD raw_to_string.DATA: lv_output_length TYPE i,lt_binary_tab    TYPE STANDARD TABLE OF sdokcntbin.CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'EXPORTINGbuffer        = iv_xstringIMPORTINGoutput_length = lv_output_lengthTABLESbinary_tab    = lt_binary_tab.CALL FUNCTION 'SCMS_BINARY_TO_STRING'EXPORTINGinput_length  = lv_output_lengthencoding      = iv_encodingIMPORTINGtext_buffer   = rv_stringoutput_length = lv_output_lengthTABLESbinary_tab    = lt_binary_tab.ENDMETHOD.                    "RAW_TO_STRING* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZCL_JSON->RESTORE
* +-------------------------------------------------------------------------------------------------+
* | [--->] JSON                           TYPE        JSON
* | [--->] LENGTH                         TYPE        I
* | [--->] TYPE_DESCR                     TYPE REF TO CL_ABAP_TYPEDESCR(optional)
* | [--->] FIELD_CACHE                    TYPE        T_T_FIELD_CACHE(optional)
* | [<-->] DATA                           TYPE        DATA(optional)
* | [<-->] OFFSET                         TYPE        I (default =0)
* | [!CX!] CX_SY_MOVE_CAST_ERROR
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD restore.DATA: mark       LIKE offset,match      LIKE offset,ref_descr  TYPE REF TO cl_abap_refdescr,data_descr TYPE REF TO cl_abap_datadescr,data_ref   TYPE REF TO data,object_ref TYPE REF TO object,fields     LIKE field_cache,name_json  TYPE string.FIELD-SYMBOLS: <value>       TYPE any,<field_cache> LIKE LINE OF field_cache.DATA: BEGIN OF t_p_fields,name         TYPE string,type         TYPE REF TO cl_abap_datadescr,convexit_out TYPE string,convexit_in  TYPE string,value        TYPE REF TO data,END OF t_p_fields.DATA: p_fields LIKE TABLE OF t_p_fields.LOOP AT field_cache ASSIGNING <field_cache>.APPEND <field_cache> to p_fields.ENDLOOP.fields = field_cache.IF type_descr IS NOT INITIAL AND type_descr->kind EQ type_descr->kind_ref.ref_descr ?= type_descr.type_descr = ref_descr->get_referenced_type( ).IF ref_descr->type_kind EQ ref_descr->typekind_oref.IF data IS INITIAL." can fire an exception, if type is abstract or constructor protectedCREATE OBJECT data TYPE (type_descr->absolute_name).ENDIF.object_ref ?= data.fields = get_fields( type_descr = type_descr object = object_ref ).ELSEIF ref_descr->type_kind EQ ref_descr->typekind_dref.IF data IS INITIAL.data_descr ?= type_descr.CREATE DATA data TYPE HANDLE data_descr.ENDIF.data_ref ?= data.ASSIGN data_ref->* TO <value>.fields = get_fields( type_descr = type_descr data = data_ref ).restore( EXPORTING json = json length = length type_descr = type_descr field_cache = fieldsCHANGING data = <value> offset = offset ).RETURN.ENDIF.ENDIF.IF fields IS INITIAL AND type_descr IS NOT INITIAL AND type_descr->kind EQ type_descr->kind_struct.GET REFERENCE OF data INTO data_ref.fields = get_fields( type_descr = type_descr data = data_ref ).ENDIF.eat_white.eat_char `{`.eat_white.WHILE offset < length AND json+offset(1) NE `}`.eat_name name_json.eat_white.eat_char `:`.eat_white.READ TABLE fields WITH TABLE KEY name = name_json ASSIGNING <field_cache>.IF sy-subrc IS NOT INITIAL.TRANSLATE name_json TO UPPER CASE.READ TABLE fields WITH TABLE KEY name = name_json ASSIGNING <field_cache>.ENDIF.IF sy-subrc IS INITIAL.ASSIGN <field_cache>-value->* TO <value>.restore_type( EXPORTING json = json length = length type_descr = <field_cache>-type convexit = <field_cache>-convexit_in CHANGING data = <value> offset = offset ).ELSE.restore_type( EXPORTING json = json length = length CHANGING offset = offset ).ENDIF.eat_white.IF offset < length AND json+offset(1) NE `}`.eat_char `,`.eat_white.ELSE.EXIT.ENDIF.ENDWHILE.eat_char `}`.ENDMETHOD.                    "RESTORE* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZCL_JSON->RESTORE_TYPE
* +-------------------------------------------------------------------------------------------------+
* | [--->] JSON                           TYPE        JSON
* | [--->] LENGTH                         TYPE        I
* | [--->] TYPE_DESCR                     TYPE REF TO CL_ABAP_TYPEDESCR(optional)
* | [--->] FIELD_CACHE                    TYPE        T_T_FIELD_CACHE(optional)
* | [--->] CONVEXIT                       TYPE        STRING(optional)
* | [<-->] DATA                           TYPE        DATA(optional)
* | [<-->] OFFSET                         TYPE        I (default =0)
* | [!CX!] CX_SY_MOVE_CAST_ERROR
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD restore_type.DATA: mark        LIKE offset,match       LIKE offset,sdummy      TYPE string,                         "#EC NEEDEDrdummy      TYPE REF TO data,                    "#EC NEEDEDpos         LIKE offset,line        TYPE REF TO data,key_ref     TYPE REF TO data,data_ref    TYPE REF TO data,key_name    TYPE string,key_value   TYPE string,lt_fields   LIKE field_cache,lt_symbols  TYPE t_t_symbol,lv_ticks    TYPE string,lv_offset   TYPE string,lv_convexit LIKE convexit,lo_exp      TYPE REF TO cx_root,elem_descr  TYPE REF TO cl_abap_elemdescr,table_descr TYPE REF TO cl_abap_tabledescr,data_descr  TYPE REF TO cl_abap_datadescr.FIELD-SYMBOLS: <line>      TYPE any,<value>     TYPE any,<data>      TYPE data,<field>     LIKE LINE OF lt_fields,<table>     TYPE ANY TABLE,<value_sym> LIKE LINE OF lt_symbols.lv_convexit = convexit.IF type_descr IS INITIAL AND data IS SUPPLIED.type_descr = cl_abap_typedescr=>describe_by_data( data ).IF mv_conversion_exits EQ abap_true AND lv_convexit IS INITIAL AND type_descr->kind EQ cl_abap_typedescr=>kind_elem.elem_descr ?= type_descr.lv_convexit = get_convexit_func( elem_descr = elem_descr input = abap_true ).ENDIF.ENDIF.eat_white.TRY .IF type_descr IS NOT INITIAL AND type_descr->absolute_name EQ mc_json_type." skip deserializationmark = offset.restore_type( EXPORTING json = json length = length CHANGING offset = offset ).match = offset - mark.data = json+mark(match).ENDIF.CASE json+offset(1).WHEN `{`. " objectIF type_descr IS NOT INITIAL.IF mv_assoc_arrays EQ c_bool-true AND type_descr->kind EQ cl_abap_typedescr=>kind_table.table_descr ?= type_descr.data_descr = table_descr->get_table_line_type( ).IF table_descr->has_unique_key IS NOT INITIAL.eat_char `{`.eat_white.IF json+offset(1) NE `}`.ASSIGN data TO <table>.CLEAR <table>.CREATE DATA line LIKE LINE OF <table>.ASSIGN line->* TO <line>.lt_fields = get_fields( type_descr = data_descr data = line ).IF table_descr->key_defkind EQ table_descr->keydefkind_user AND lines( table_descr->key ) EQ 1.READ TABLE table_descr->key INDEX 1 INTO key_name.READ TABLE lt_fields WITH TABLE KEY name = key_name ASSIGNING <field>.key_ref = <field>-value.IF mv_assoc_arrays_opt EQ c_bool-true.lt_symbols = get_symbols( type_descr = data_descr data = line ).DELETE lt_symbols WHERE name EQ key_name.IF lines( lt_symbols ) EQ 1.READ TABLE lt_symbols INDEX 1 ASSIGNING <value_sym>.ENDIF.ENDIF.ENDIF.eat_white.WHILE offset < length AND json+offset(1) NE `}`.CLEAR <line>.eat_name key_value.eat_white.eat_char `:`.eat_white.IF <value_sym> IS ASSIGNED.ASSIGN <value_sym>-value->* TO <value>.restore_type( EXPORTING json = json length = length type_descr = <value_sym>-type convexit = <value_sym>-convexit_inCHANGING data = <value> offset = offset ).ELSE.restore_type( EXPORTING json = json length = length type_descr = data_descr field_cache = lt_fieldsCHANGING data = <line> offset = offset ).ENDIF.IF table_descr->key_defkind EQ table_descr->keydefkind_user.IF key_ref IS BOUND.ASSIGN key_ref->* TO <value>.IF <value> IS INITIAL.<value> = key_value.ENDIF.ENDIF.ELSEIF <line> IS INITIAL.<line> = key_value.ENDIF.INSERT <line> INTO TABLE <table>.eat_white.IF offset < length AND json+offset(1) NE `}`.eat_char `,`.eat_white.ELSE.EXIT.ENDIF.ENDWHILE.ELSE.CLEAR data.ENDIF.eat_char `}`.ELSE.restore( EXPORTING json = json length = length CHANGING  offset = offset ).ENDIF.ELSEIF type_descr->type_kind EQ cl_abap_typedescr=>typekind_dref.IF data IS INITIAL.generate_int_ex( EXPORTING json = json length = length CHANGING offset = offset data = data ).ELSE.data_ref ?= data.type_descr = cl_abap_typedescr=>describe_by_data_ref( data_ref ).ASSIGN data_ref->* TO <data>.restore_type( EXPORTING json = json length = length type_descr = type_descr CHANGING data = <data> offset = offset ).ENDIF.ELSE.restore( EXPORTING json = json length = length type_descr = type_descr field_cache = field_cacheCHANGING data = data offset = offset ).ENDIF.ELSE.restore( EXPORTING json = json length = length CHANGING  offset = offset ).ENDIF.WHEN `[`. " arrayIF type_descr IS NOT INITIAL AND type_descr->type_kind EQ cl_abap_typedescr=>typekind_dref.IF data IS INITIAL.generate_int_ex( EXPORTING json = json length = length CHANGING offset = offset data = data ).ELSE.data_ref ?= data.type_descr = cl_abap_typedescr=>describe_by_data_ref( data_ref ).ASSIGN data_ref->* TO <data>.restore_type( EXPORTING json = json length = length type_descr = type_descr CHANGING data = <data> offset = offset ).ENDIF.ELSE.eat_char `[`.eat_white.IF json+offset(1) NE `]`.IF type_descr IS NOT INITIAL AND type_descr->kind EQ cl_abap_typedescr=>kind_table.table_descr ?= type_descr.data_descr = table_descr->get_table_line_type( ).ASSIGN data TO <table>.CLEAR <table>.CREATE DATA line LIKE LINE OF <table>.ASSIGN line->* TO <line>.lt_fields = get_fields( type_descr = data_descr data = line ).WHILE offset < length AND json+offset(1) NE `]`.CLEAR <line>.restore_type( EXPORTING json = json length = length type_descr = data_descr field_cache = lt_fieldsCHANGING data = <line> offset = offset ).INSERT <line> INTO TABLE <table>.eat_white.IF offset < length AND json+offset(1) NE `]`.eat_char `,`.eat_white.ELSE.EXIT.ENDIF.ENDWHILE.ELSE." skip arrayeat_white.WHILE offset < length AND json+offset(1) NE `]`.restore_type( EXPORTING json = json length = length CHANGING offset = offset ).eat_white.IF offset < length AND json+offset(1) NE `]`.eat_char `,`.eat_white.ELSE.EXIT.ENDIF.ENDWHILE.IF type_descr IS NOT INITIAL.eat_char `]`.throw_error.ENDIF.ENDIF.ELSE.CLEAR data.ENDIF.eat_char `]`.ENDIF.WHEN `"`. " stringeat_string sdummy.IF type_descr IS NOT INITIAL." unescape stringIF sdummy IS NOT INITIAL.IF type_descr->kind EQ cl_abap_typedescr=>kind_elem.elem_descr ?= type_descr.IF lv_convexit IS NOT INITIAL.TRY .CALL FUNCTION lv_convexitEXPORTINGinput         = sdummyIMPORTINGoutput        = dataEXCEPTIONSerror_message = 2OTHERS        = 1.IF sy-subrc IS INITIAL.RETURN.ENDIF.CATCH cx_root.                    "#EC NO_HANDLERENDTRY.ENDIF.CASE elem_descr->type_kind.WHEN cl_abap_typedescr=>typekind_char.IF elem_descr->output_length EQ 1 AND mc_bool_types CS elem_descr->absolute_name.IF sdummy(1) CA `XxTt1`.data = c_bool-true.ELSE.data = c_bool-false.ENDIF.RETURN.ENDIF.WHEN cl_abap_typedescr=>typekind_xstring.string_to_xstring( EXPORTING in = sdummy CHANGING out = data ).RETURN.WHEN cl_abap_typedescr=>typekind_hex." support for Edm.GuidREPLACE FIRST OCCURRENCE OF REGEX `^([0-9A-F]{8})-([0-9A-F]{4})-([0-9A-F]{4})-([0-9A-F]{4})-([0-9A-F]{12})$` IN sdummyWITH `$1$2$3$4$5` REPLACEMENT LENGTH match. "#EC NOTEXTIF sy-subrc EQ 0.data = sdummy(match).ELSE.string_to_xstring( EXPORTING in = sdummy CHANGING out = data ).ENDIF.RETURN.WHEN cl_abap_typedescr=>typekind_date." support for ISO8601 => https://en.wikipedia.org/wiki/ISO_8601REPLACE FIRST OCCURRENCE OF REGEX `^(\d{4})-(\d{2})-(\d{2})` IN sdummy WITH `$1$2$3`REPLACEMENT LENGTH match.             "#EC NOTEXTIF sy-subrc EQ 0.sdummy = sdummy(match).ELSE." support for Edm.DateTime => http://www.odata.org/documentation/odata-version-2-0/json-format/FIND FIRST OCCURRENCE OF REGEX `^\/Date\((-?\d+)([+-]\d{1,4})?\)\/` IN sdummy SUBMATCHES lv_ticks lv_offset IGNORING CASE. "#EC NOTEXTIF sy-subrc EQ 0.sdummy = edm_datetime_to_ts( ticks = lv_ticks offset = lv_offset typekind = elem_descr->type_kind ).ELSE." support for Edm.Time => https://www.w3.org/TR/xmlschema11-2/#nt-durationRepREPLACE FIRST OCCURRENCE OF REGEX `^-?P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)(?:\.(\d+))?S)?)?` IN sdummy WITH `$1$2$3`REPLACEMENT LENGTH match.         "#EC NOTEXTIF sy-subrc EQ 0.sdummy = sdummy(match).ENDIF.ENDIF.ENDIF.WHEN cl_abap_typedescr=>typekind_time." support for ISO8601 => https://en.wikipedia.org/wiki/ISO_8601REPLACE FIRST OCCURRENCE OF REGEX `^(\d{2}):(\d{2}):(\d{2})` IN sdummy WITH `$1$2$3`REPLACEMENT LENGTH match.             "#EC NOTEXTIF sy-subrc EQ 0.sdummy = sdummy(match).ELSE." support for Edm.DateTime => http://www.odata.org/documentation/odata-version-2-0/json-format/FIND FIRST OCCURRENCE OF REGEX '^\/Date\((-?\d+)([+-]\d{1,4})?\)\/' IN sdummy SUBMATCHES lv_ticks lv_offset IGNORING CASE. "#EC NOTEXTIF sy-subrc EQ 0.sdummy = edm_datetime_to_ts( ticks = lv_ticks offset = lv_offset typekind = elem_descr->type_kind ).ELSE." support for Edm.Time => https://www.w3.org/TR/xmlschema11-2/#nt-durationRepREPLACE FIRST OCCURRENCE OF REGEX `^-?P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)(?:\.(\d+))?S)?)?` IN sdummy WITH `$4$5$6`REPLACEMENT LENGTH match.         "#EC NOTEXTIF sy-subrc EQ 0.sdummy = sdummy(match).ENDIF.ENDIF.ENDIF.WHEN cl_abap_typedescr=>typekind_packed.REPLACE FIRST OCCURRENCE OF REGEX `^(\d{4})-?(\d{2})-?(\d{2})T(\d{2}):?(\d{2}):?(\d{2})(?:[\.,](\d{0,7}))?Z?` IN sdummy WITH `$1$2$3$4$5$6.$7`REPLACEMENT LENGTH match.             "#EC NOTEXTIF sy-subrc EQ 0.sdummy = sdummy(match).ELSE.FIND FIRST OCCURRENCE OF REGEX '^\/Date\((-?\d+)([+-]\d{1,4})?\)\/' IN sdummy SUBMATCHES lv_ticks lv_offset IGNORING CASE. "#EC NOTEXTIF sy-subrc EQ 0.sdummy = edm_datetime_to_ts( ticks = lv_ticks offset = lv_offset typekind = elem_descr->type_kind ).ELSE." support for Edm.Time => https://www.w3.org/TR/xmlschema11-2/#nt-durationRepREPLACE FIRST OCCURRENCE OF REGEX `^-?P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)(?:\.(\d+))?S)?)?` IN sdummy WITH `$1$2$3$4$5$6.$7`REPLACEMENT LENGTH match.         "#EC NOTEXTIF sy-subrc EQ 0.sdummy = sdummy(match).ENDIF.ENDIF.ENDIF.WHEN `k`. "cl_abap_typedescr=>typekind_enumTRY.CALL METHOD ('CL_ABAP_XSD')=>('TO_VALUE')EXPORTINGcs  = sdummyCHANGINGval = data.RETURN.CATCH cx_sy_dyn_call_error.throw_error. " Deserialization of enums is not supportedENDTRY.ENDCASE.ELSEIF type_descr->type_kind EQ cl_abap_typedescr=>typekind_dref.CREATE DATA rdummy TYPE string.ASSIGN rdummy->* TO <data>.<data> = sdummy.data ?= rdummy.RETURN.ELSE.throw_error. " Other wise dumps with OBJECTS_MOVE_NOT_SUPPORTEDENDIF.data = sdummy.ELSEIF type_descr->kind EQ cl_abap_typedescr=>kind_elem.CLEAR data.ELSE.throw_error. " Other wise dumps with OBJECTS_MOVE_NOT_SUPPORTEDENDIF.ENDIF.WHEN `-` OR `0` OR `1` OR `2` OR `3` OR `4` OR `5` OR `6` OR `7` OR `8` OR `9`. " numberIF type_descr IS NOT INITIAL.IF type_descr->kind EQ type_descr->kind_ref AND type_descr->type_kind EQ cl_abap_typedescr=>typekind_dref.eat_number sdummy.                          "#EC NOTEXTmatch = strlen( sdummy ).IF sdummy CS '.'. " float.CREATE DATA rdummy TYPE f.ELSEIF match GT 9. " packedCREATE DATA rdummy TYPE p.ELSE. " integerCREATE DATA rdummy TYPE i.ENDIF.ASSIGN rdummy->* TO <data>.<data> = sdummy.data ?= rdummy.ELSEIF type_descr->kind EQ type_descr->kind_elem.IF lv_convexit IS NOT INITIAL.TRY .eat_number sdummy.                    "#EC NOTEXTCALL FUNCTION lv_convexitEXPORTINGinput         = sdummyIMPORTINGoutput        = dataEXCEPTIONSerror_message = 2OTHERS        = 1.IF sy-subrc IS INITIAL.RETURN.ENDIF.CATCH cx_root.                      "#EC NO_HANDLERENDTRY.ENDIF.eat_number data.                            "#EC NOTEXTELSE.eat_number sdummy.                          "#EC NOTEXTthrow_error.ENDIF.ELSE.eat_number sdummy.                            "#EC NOTEXTENDIF.WHEN OTHERS. " boolean, e.g true/false/nullIF type_descr IS NOT INITIAL.IF type_descr->kind EQ type_descr->kind_ref AND type_descr->type_kind EQ cl_abap_typedescr=>typekind_dref.CREATE DATA rdummy TYPE bool.ASSIGN rdummy->* TO <data>.eat_bool <data>.                            "#EC NOTEXTdata ?= rdummy.ELSEIF type_descr->kind EQ type_descr->kind_elem.eat_bool data.                              "#EC NOTEXTELSE.eat_bool sdummy.                            "#EC NOTEXTthrow_error.ENDIF.ELSE.eat_bool sdummy.                              "#EC NOTEXTENDIF.ENDCASE.CATCH cx_sy_move_cast_error cx_sy_conversion_no_number cx_sy_conversion_overflow INTO lo_exp.CLEAR data.IF mv_strict_mode EQ abap_true.RAISE EXCEPTION TYPE cx_sy_move_cast_errorEXPORTINGprevious = lo_exp.ENDIF.ENDTRY.ENDMETHOD.                    "RESTORE_TYPE* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON=>SERIALIZE
* +-------------------------------------------------------------------------------------------------+
* | [--->] DATA                           TYPE        DATA
* | [--->] COMPRESS                       TYPE        BOOL (default =C_BOOL-FALSE)
* | [--->] NAME                           TYPE        STRING(optional)
* | [--->] PRETTY_NAME                    TYPE        PRETTY_NAME_MODE (default =PRETTY_MODE-NONE)
* | [--->] TYPE_DESCR                     TYPE REF TO CL_ABAP_TYPEDESCR(optional)
* | [--->] ASSOC_ARRAYS                   TYPE        BOOL (default =C_BOOL-FALSE)
* | [--->] TS_AS_ISO8601                  TYPE        BOOL (default =C_BOOL-FALSE)
* | [--->] EXPAND_INCLUDES                TYPE        BOOL (default =C_BOOL-TRUE)
* | [--->] ASSOC_ARRAYS_OPT               TYPE        BOOL (default =C_BOOL-FALSE)
* | [--->] NUMC_AS_STRING                 TYPE        BOOL (default =C_BOOL-FALSE)
* | [--->] NAME_MAPPINGS                  TYPE        NAME_MAPPINGS(optional)
* | [--->] CONVERSION_EXITS               TYPE        BOOL (default =C_BOOL-FALSE)
* | [<-()] R_JSON                         TYPE        JSON
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD serialize." **********************************************************************" Usage examples and documentation can be found on SCN:" http://wiki.scn.sap.com/wiki/display/Snippets/One+more+ABAP+to+JSON+Serializer+and+Deserializer" **********************************************************************  "DATA: lo_json  TYPE REF TO zcl_json.CREATE OBJECT lo_jsonEXPORTINGcompress         = compresspretty_name      = pretty_namename_mappings    = name_mappingsassoc_arrays     = assoc_arraysassoc_arrays_opt = assoc_arrays_optexpand_includes  = expand_includesnumc_as_string   = numc_as_stringconversion_exits = conversion_exitsts_as_iso8601    = ts_as_iso8601.r_json = lo_json->serialize_int( name = name data = data type_descr = type_descr ).ENDMETHOD.                    "SERIALIZE* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_JSON->SERIALIZE_INT
* +-------------------------------------------------------------------------------------------------+
* | [--->] DATA                           TYPE        DATA
* | [--->] NAME                           TYPE        STRING(optional)
* | [--->] TYPE_DESCR                     TYPE REF TO CL_ABAP_TYPEDESCR(optional)
* | [<-()] R_JSON                         TYPE        JSON
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD serialize_int." **********************************************************************" Usage examples and documentation can be found on SCN:" http://wiki.scn.sap.com/wiki/display/Snippets/One+more+ABAP+to+JSON+Serializer+and+Deserializer" **********************************************************************  "DATA: lo_descr      TYPE REF TO cl_abap_typedescr,lo_elem_descr TYPE REF TO cl_abap_elemdescr,lv_convexit   TYPE string.IF type_descr IS INITIAL.lo_descr = cl_abap_typedescr=>describe_by_data( data ).ELSE.lo_descr = type_descr.ENDIF.IF mv_conversion_exits EQ abap_true AND lo_descr->kind EQ cl_abap_typedescr=>kind_elem.lo_elem_descr ?= lo_descr.lv_convexit = get_convexit_func( elem_descr = lo_elem_descr input = abap_false ).ENDIF.r_json = dump_int( data = data type_descr = lo_descr convexit = lv_convexit )." we do not do escaping of every single string value for white space characters," but we do it on top, to replace multiple calls by 3 only, while we do not serialize" outlined/formatted JSON this shall not produce any harmREPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>cr_lf          IN r_json WITH `\r\n`.REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>newline        IN r_json WITH `\n`.REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>horizontal_tab IN r_json WITH `\t`.
* REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>form_feed      IN r_json WITH `\f`.
* REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>backspace      IN r_json WITH `\b`.IF name IS NOT INITIAL AND ( mv_compress IS INITIAL OR r_json IS NOT INITIAL ).CONCATENATE `"` name `":` r_json INTO r_json.ENDIF.ENDMETHOD.                    "SERIALIZE_INT* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON=>STRING_TO_RAW
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_STRING                      TYPE        STRING
* | [--->] IV_ENCODING                    TYPE        ABAP_ENCODING(optional)
* | [<-()] RV_XSTRING                     TYPE        XSTRING
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD string_to_raw.CALL FUNCTION 'SCMS_STRING_TO_XSTRING'EXPORTINGtext     = iv_stringencoding = iv_encodingIMPORTINGbuffer   = rv_xstringEXCEPTIONSOTHERS   = 1.IF sy-subrc IS NOT INITIAL.CLEAR rv_xstring.ENDIF.ENDMETHOD.                    "STRING_TO_RAW* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON=>STRING_TO_XSTRING
* +-------------------------------------------------------------------------------------------------+
* | [--->] IN                             TYPE        STRING
* | [<-->] OUT                            TYPE        ANY
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD string_to_xstring.DATA: lv_xstring TYPE xstring.CALL FUNCTION 'SSFC_BASE64_DECODE'EXPORTINGb64data = inIMPORTINGbindata = lv_xstringEXCEPTIONSOTHERS  = 1.IF sy-subrc IS INITIAL.out = lv_xstring.ELSE.out = in.ENDIF.ENDMETHOD.                    "STRING_TO_XSTRING* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON=>TRIBOOL_TO_BOOL
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_TRIBOOL                     TYPE        TRIBOOL
* | [<-()] RV_BOOL                        TYPE        BOOL
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD tribool_to_bool.IF iv_tribool EQ c_tribool-true.rv_bool = c_bool-true.ELSEIF iv_tribool EQ c_tribool-undefined.rv_bool = abap_undefined. " fall back to abap_undefinedENDIF.ENDMETHOD.                    "TRIBOOL_TO_BOOL* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Protected Method ZCL_JSON=>UNESCAPE
* +-------------------------------------------------------------------------------------------------+
* | [--->] ESCAPED                        TYPE        STRING
* | [<-()] UNESCAPED                      TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD unescape.DATA: lv_offset           TYPE i,lv_match            TYPE i,lv_delta            TYPE i,lv_length           TYPE i,lv_offset_e         TYPE i,lv_length_e         TYPE i,lv_unicode_symb     TYPE c,lv_unicode_escaped  TYPE string,lt_matches          TYPE match_result_tab.FIELD-SYMBOLS: <match> LIKE LINE OF lt_matches." see reference for escaping rules in JSON RFC" https://www.ietf.org/rfc/rfc4627.txtunescaped = escaped.lv_length = strlen( unescaped ).FIND FIRST OCCURRENCE OF REGEX `\\[rntfbu]` IN unescaped RESPECTING CASE.IF sy-subrc IS INITIAL.FIND ALL OCCURRENCES OF REGEX `\\.` IN unescaped RESULTS lt_matches RESPECTING CASE.LOOP AT lt_matches ASSIGNING <match>.lv_match  = <match>-offset - lv_delta.lv_offset = lv_match + 1.CASE unescaped+lv_offset(1).WHEN `r`.REPLACE SECTION OFFSET lv_match LENGTH 2 OF unescaped WITH cl_abap_char_utilities=>cr_lf(1).lv_delta = lv_delta + 1.WHEN `n`.REPLACE SECTION OFFSET lv_match LENGTH 2 OF unescaped WITH cl_abap_char_utilities=>newline.lv_delta = lv_delta + 1.WHEN `t`.REPLACE SECTION OFFSET lv_match LENGTH 2 OF unescaped WITH cl_abap_char_utilities=>horizontal_tab.lv_delta = lv_delta + 1.WHEN `f`.REPLACE SECTION OFFSET lv_match LENGTH 2 OF unescaped WITH cl_abap_char_utilities=>form_feed.lv_delta = lv_delta + 1.WHEN `b`.REPLACE SECTION OFFSET lv_match LENGTH 2 OF unescaped WITH cl_abap_char_utilities=>backspace.lv_delta = lv_delta + 1.WHEN `u`.lv_offset   = lv_offset + 1.lv_offset_e = lv_offset + 4.lv_length_e = lv_length + lv_delta.IF lv_offset_e LE lv_length_e.lv_unicode_escaped = unescaped+lv_offset(4).TRANSLATE lv_unicode_escaped TO UPPER CASE.lv_unicode_symb = cl_abap_conv_in_ce=>uccp( lv_unicode_escaped ).IF lv_unicode_symb NE mc_cov_error.REPLACE SECTION OFFSET lv_match LENGTH 6 OF unescaped WITH lv_unicode_symb.lv_delta = lv_delta + 5.ENDIF.ENDIF.ENDCASE.ENDLOOP.ENDIF." based on RFC mentioned above, _any_ character can be escaped, and so shall be enscaped" the only exception is Unicode symbols, that shall be kept untouched, while serializer does not handle them" unescaped singe characters, e.g \\, \", \/ etcREPLACE ALL OCCURRENCES OF REGEX `\\(.)` IN unescaped WITH `$1` RESPECTING CASE.ENDMETHOD.                    "UNESCAPE* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_JSON=>XSTRING_TO_STRING
* +-------------------------------------------------------------------------------------------------+
* | [--->] IN                             TYPE        ANY
* | [<-()] OUT                            TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD xstring_to_string.DATA: lv_xstring TYPE xstring." let us fix data conversion issues herelv_xstring = in.CALL FUNCTION 'SSFC_BASE64_ENCODE'EXPORTINGbindata = lv_xstringIMPORTINGb64data = outEXCEPTIONSOTHERS  = 1.IF sy-subrc IS NOT INITIAL.out = in.ENDIF.ENDMETHOD.                    "XSTRING_TO_STRING
ENDCLASS.

点击下图红框按钮。

复制粘贴下面代码

*"* use this source file for the definition and implementation of
*"* local helper classes, interface definitions and type
*"* declarations*"* local class implementation for public class
*"* use this source file for the implementation part of
*"* local helper classesDEFINE escape_json_inplace.
*  replace all occurrences of regex `[\\"]` in &1 with `\\$0`. <-- this is slower than 2 plain replacesreplace all occurrences of `\` in &1 with `\\`.replace all occurrences of `"` in &1 with `\"`.
END-OF-DEFINITION.DEFINE escape_json.&2 = &1.escape_json_inplace &2.
END-OF-DEFINITION.DEFINE is_compressable.if mv_extended is initial.&3 = abap_true.else.&3 = is_compressable( type_descr = &1 name = &2 ).endif.
END-OF-DEFINITION.DEFINE dump_type.if mv_extended is initial.dump_type_int &1 &2 &3 &4.else.&3 = dump_type( data = &1 type_descr = &2 convexit = &4 ).endif.
END-OF-DEFINITION.DEFINE dump_type_int.if &4 is not initial and &1 is not initial.try.call function &4exportinginput    = &1importingoutput   = &3exceptionsothers   = 1.if sy-subrc is initial.concatenate `"` &3 `"` into &3.endif.catch cx_root.                                    "#EC NO_HANDLERendtry.else.case &2->type_kind.when cl_abap_typedescr=>typekind_float or cl_abap_typedescr=>typekind_int or cl_abap_typedescr=>typekind_int1 orcl_abap_typedescr=>typekind_int2 or cl_abap_typedescr=>typekind_packed or `8`. " TYPEKIND_INT8 -> '8' only from 7.40.if &2->type_kind eq cl_abap_typedescr=>typekind_packed and mv_ts_as_iso8601 eq c_bool-true and &2->absolute_name cp `\TYPE=TIMESTAMP*`.if &1 is initial.&3 = `""`.else.&3 = &1.if &2->absolute_name eq `\TYPE=TIMESTAMP`.concatenate `"` &3(4) `-` &3+4(2) `-` &3+6(2) `T` &3+8(2) `:` &3+10(2) `:` &3+12(2) `.0000000Z"`  into &3.elseif &2->absolute_name eq `\TYPE=TIMESTAMPL`.concatenate `"` &3(4) `-` &3+4(2) `-` &3+6(2) `T` &3+8(2) `:` &3+10(2) `:` &3+12(2) `.` &3+15(7) `Z"`  into &3.endif.endif.elseif &1 is initial.&3 = `0`.else.&3 = &1.if &1 lt 0.if &2->type_kind <> cl_abap_typedescr=>typekind_float. "float: sign is already at the beginningshift &3 right circular.endif.else.condense &3.endif.endif.when cl_abap_typedescr=>typekind_num.if mv_numc_as_string eq abap_true.if &1 is initial.&3 = `""`.else.concatenate `"` &1 `"` into &3.endif.else.&3 = &1.shift &3 left deleting leading ` 0`.if &3 is initial.&3 = `0`.endif.endif.when cl_abap_typedescr=>typekind_string or cl_abap_typedescr=>typekind_csequence or cl_abap_typedescr=>typekind_clike.if &1 is initial.&3 = `""`.elseif &2->absolute_name eq mc_json_type.&3 = &1.else.escape_json &1 &3.concatenate `"` &3 `"` into &3.endif.when cl_abap_typedescr=>typekind_xstring or cl_abap_typedescr=>typekind_hex.if &1 is initial.&3 = `""`.else.&3 = xstring_to_string( &1 ).escape_json_inplace &3.concatenate `"` &3 `"` into &3.endif.when cl_abap_typedescr=>typekind_char.if &2->output_length eq 1 and mc_bool_types cs &2->absolute_name.if &1 eq c_bool-true.&3 = `true`.                                    "#EC NOTEXTelseif mc_bool_3state cs &2->absolute_name and &1 is initial.&3 = `null`.                                    "#EC NOTEXTelse.&3 = `false`.                                   "#EC NOTEXTendif.else.escape_json &1 &3.concatenate `"` &3 `"` into &3.endif.when cl_abap_typedescr=>typekind_date.concatenate `"` &1(4) `-` &1+4(2) `-` &1+6(2) `"` into &3.when cl_abap_typedescr=>typekind_time.concatenate `"` &1(2) `:` &1+2(2) `:` &1+4(2) `"` into &3.when `k`. " cl_abap_typedescr=>typekind_enum&3 = &1.concatenate `"` &3 `"` into &3.when others.if &1 is initial.&3 = `null`.                                      "#EC NOTEXTelse.&3 = &1.endif.endcase.endif.END-OF-DEFINITION.DEFINE format_name.case &2.when pretty_mode-camel_case.&3 = pretty_name( &1 ).when pretty_mode-extended.&3 = pretty_name_ex( &1 ).when pretty_mode-user_low_case.read table mt_name_mappings with table key abap = &1 assigning <cache>. "#EC WARNOKif sy-subrc is initial.&3 = <cache>-json.else.&3 = &1.translate &3 to lower case.                       "#EC SYNTCHARendif.when pretty_mode-user.read table mt_name_mappings with table key abap = &1 assigning <cache>. "#EC WARNOKif sy-subrc is initial.&3 = <cache>-json.else.&3 = &1.endif.when pretty_mode-low_case.&3 = &1.translate &3 to lower case.                         "#EC SYNTCHARwhen others.&3 = &1.endcase.
END-OF-DEFINITION.DEFINE throw_error.raise exception type cx_sy_move_cast_error.
END-OF-DEFINITION.DEFINE while_offset_cs.
*  >= 7.02 alternative
*  pos = find_any_not_of( val = json sub = &1 off = offset ).
*  if pos eq -1. offset = length.
*  else. offset = pos. endif.* < 7.02while offset < length.find first occurrence of json+offset(1) in &1.if sy-subrc is not initial.exit.endif.offset = offset + 1.endwhile.
* < 7.02END-OF-DEFINITION.DEFINE while_offset_not_cs.while offset < length.find first occurrence of &2+offset(1) in &1.if sy-subrc is initial.exit.endif.offset = offset + 1.endwhile.
END-OF-DEFINITION.DEFINE eat_white.while_offset_cs sv_white_space.if offset ge length.throw_error.endif.
END-OF-DEFINITION.DEFINE eat_name.if json+offset(1) eq `"`.mark   = offset + 1.offset = mark.find first occurrence of `"` in section offset offset of json match offset offset.if sy-subrc is not initial.throw_error.endif.match = offset - mark.&1 = json+mark(match).offset = offset + 1.else.throw_error.endif.
END-OF-DEFINITION.DEFINE eat_string.if json+offset(1) eq `"`.mark   = offset + 1.offset = mark.do.find first occurrence of `"` in section offset offset of json match offset pos.if sy-subrc is not initial.throw_error.endif.offset = pos.pos = pos - 1." if escaped search furtherwhile pos ge 0 and json+pos(1) eq `\`.pos = pos - 1.endwhile.match = ( offset - pos ) mod 2.if match ne 0.exit.endif.offset = offset + 1.enddo.match = offset - mark.&1 = json+mark(match)." unescaped singe characters, e.g \\, \", \/ etc," BUT ONLY if someone really need the dataif type_descr is not initial.&1 = unescape( &1 ).endif.offset = offset + 1.else.throw_error.endif.
END-OF-DEFINITION.DEFINE eat_number.mark   = offset.while_offset_cs `0123456789+-eE.`.                        "#EC NOTEXTmatch = offset - mark.&1 = json+mark(match).
END-OF-DEFINITION.DEFINE eat_bool.mark   = offset.while_offset_cs `aeflnrstu`.                              "#EC NOTEXTmatch = offset - mark.if json+mark(match) eq `true`.                            "#EC NOTEXT&1 = c_bool-true.elseif json+mark(match) eq `false`.                       "#EC NOTEXTif type_descr is bound and mc_bool_3state cs type_descr->absolute_name.&1 = c_tribool-false.else.&1 = c_bool-false.endif.elseif json+mark(match) eq `null`.                        "#EC NOTEXTclear &1.endif.
END-OF-DEFINITION.DEFINE eat_char.if offset < length and json+offset(1) eq &1.offset = offset + 1.else.throw_error.endif.
END-OF-DEFINITION.

激活,至此完成。

可用下面代码测试。

REPORT zrtest2NO STANDARD PAGE HEADING LINE-SIZE 255.data: lv_json_str type string.data: begin of ls_data,matnr like mara-matnr,end of ls_data.data: ls_data2 like ls_data.ls_data-matnr = '20231106'.CALL METHOD zcl_json=>serializeEXPORTINGdata           = ls_data"pretty_name    = iv_pretty_namenumc_as_string = 'X'RECEIVINGr_json         = lv_json_str.CALL METHOD zcl_json=>deserializeEXPORTINGjson = lv_json_strCHANGINGdata = ls_data2.if sy-subrc = 0.endif.

测试结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/184595.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一杯子三变:揭秘vue单页应用(spa)与内容动态加载的奥秘

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、什…

视频转码教程:轻松制作GIF动态图,一键高效剪辑操作

随着社交媒体的兴起&#xff0c;GIF动态图已经成为了人们表达情感、分享精彩瞬间的重要方式。而将视频转化为GIF动态图&#xff0c;不仅可以方便地在社交媒体上分享&#xff0c;还可以延长视频的播放时长&#xff0c;吸引更多的观众。本篇文章将为大家介绍如何将视频轻松转化为…

RestTemplate配置和使用

在项目中&#xff0c;如果要调用第三方的http服务&#xff0c;就需要发起http请求&#xff0c;常用的请求方式&#xff1a;第一种&#xff0c;使用java原生发起http请求&#xff0c;这种方式不需要引入第三方库&#xff0c;但是连接不可复用&#xff0c;如果要实现连接复用&…

dgl安装教程

我在矩池云服务器上安装了一个dgl的环境&#xff0c;以后都可以用这个了 首先我的基础环境是 最终的版本如下 安装步骤如下 pip install dgl0.9.1 -f https://s3.us-west-2.amazonaws.com/dgl-data/wheels/cu113/repo.html注意不能直接使用 pip install dgl -f https://s…

51单片机-定时计数器

文章目录 前言1 原理2.编程 前言 1 原理 2.编程 定时计算&#xff1a; 50ms501000us 一个机器周期&#xff1a;1.085us 65535 - 501000/1.08546082 故 40082*1.08549998.97 /*定时器1&#xff0c;定时模式 工作模式1 16位计数器&#xff0c; 定时20秒后使能蜂鸣器*/ #include…

自定义element-ui plus 函数式调用,在API,js中直接使用全局组件

npm方式: npm install -D unplugin-vue-components unplugin-auto-import yarn 方式 : yarn add unplugin-vue-components; yarn add unplugin-auto-import; 使用官方的这个&#xff1a; vite.config.js中配置 plugins: [vue(),AutoImport({resolvers: [ElementPlusResolve…

【GEE】7、利用GEE进行遥感影像分类【随机森林分类】

1简介 在本模块中&#xff0c;我们将讨论以下概念&#xff1a; 监督和非监督图像分类之间的区别。Google Earth Engine 提供的各种分类算法的定义和应用。如何使用 randomForest 设置和运行分类&#xff0c;以 aspen 存在和不存在作为示例数据集。 2背景 图像分类 人类自然倾向…

【黑马程序员】SpringCloud——微服务

文章目录 前言一、服务架构演变1. 单体架构2. 分布式架构2.1 服务治理 3. 微服务3.1 微服务结构3.2 微服务技术对比3.3 企业需求 二、SpringCloud兼容性 三、服务拆分及远程调用1. 服务拆分1.1 服务拆分注意事项1.2 导入服务拆分 Demo 2. 远程调用2.1 根据订单 id 查询订单功能…

C++入门(二)

前言 我们上一期介绍了什么是C&#xff0c;命名空间、输入输出、以及缺省参数。本期我们来继续介绍C的入门知识&#xff01; 本期内容介绍 函数重载 引用 内联函数 auto关键字 范围for 指针空值nullptr 目录 前言 本期内容介绍 一、函数重载 什么是函数重载&#xff1f; …

排序算法之-选择

算法原理 在未排序的数列中找出最大&#xff08;或最小&#xff09;的元素&#xff0c;然后将其存入到已排序的数列起始位置&#xff0c;紧接着在剩余的未排序数列中继续查找最大&#xff08;或最小&#xff09;的元素&#xff0c;并将其放入到已排序的数列末尾&#xff0c;依…

Flink--简介

1、Apache Flink 是一个实时计算的框架和分布式处理引擎&#xff0c;用于在无边界喝有边界数据流上进行有状态的计算&#xff0c;并且能够在常见的集群上运行&#xff0c;并能以内存速度和任意规模进行计算。 有边界数据流&#xff1a;指的是有开始&#xff0c;也有结束&…

SpringMVC使用AOP监听方法推送数据

导入aop的maven依赖 <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.6.12</version> </dependency>创建一个spring的XML文件编写aop配置 <?xml version"1.0" …

推荐一款功能强大的在线文件预览工具-kkFileView

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

【Unity】思考方式与构造 | 碰撞器/刚体/预设/组件

《Unity神技大人炼成记》第二章-思考方式与构造 Unity版本&#xff1a;2019.4.23f1c1 相关文章&#xff1a;第一章&#xff1a;开天辟地&#xff08;场景搭建-天空 山脉 草木 湖泊&#xff09; 粉色矩形是截图后添加&#xff0c;以便辨认操作位置有些步骤只是为了体现一些属性…

多维时序 | MATLAB实现TCN-selfAttention自注意力机制结合时间卷积神经网络多变量时间序列预测

多维时序 | MATLAB实现TCN-selfAttention自注意力机制结合时间卷积神经网络多变量时间序列预测 目录 多维时序 | MATLAB实现TCN-selfAttention自注意力机制结合时间卷积神经网络多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现TCN-s…

深度学习之基于Tensorflow人脸面部表情识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 基于Tensorflow的人脸面部表情识别系统是一种基于深度学习技术的图像处理应用&#xff0c;该系统主要通过人脸图像数…

Stable Diffusion源码调试(二)

Stable Diffusion源码调试&#xff08;二&#xff09; 个人模型主页&#xff1a;https://liblib.ai/userpage/369b11c9952245e28ea8d107ed9c2746/model Stable Diffusion版本&#xff1a;https://github.com/AUTOMATIC1111/stable-diffusion-webui/releases/tag/v1.4.1 分析S…

nacos应用——占用内存过多问题解决(JVM调优初步)

问题描述 最近搞了一台1年的阿里云服务器&#xff0c;安装了一下常用的MySQL&#xff0c;Redis&#xff0c;rabbitmq&#xff0c;minio&#xff0c;然后有安装了一下nacos&#xff0c;结果一启动nacos内存占用就很高&#xff0c;就比较限制我继续安装其他镜像或者启动别的服务…

b2b.ccb.com:443 需要你的凭据

忙活了一天&#xff0c;晚上回来准备查一下公户的最近的账单。因为昨天晚上熬夜重新做了电脑系统&#xff0c;就下载了建设银行的E路护航&#xff0c;一切安装就绪&#xff0c;准备进入企业网银时&#xff0c;被这些垃圾搞的系统及软件恶心到了&#xff0c;在此记录一下&#x…

CAN 协议常见面试题总结

0.讲一下CAN通讯的过程 第一段&#xff1a;需要发送的通讯设备&#xff0c;先发送一个显性电平0&#xff0c;告诉其他通讯设备&#xff0c;需要开始通讯。 第二段&#xff1a;就是发送仲裁段&#xff0c;其中包括ID帧和数据帧类型&#xff0c;告诉其他通讯设备&#xff0c;需…