SE11新建结构
IKEYNA 1 Types /SCMTMS/STRING STRING 0 0 0 String
IVALUE 1 Types /SCMTMS/STRING STRING 0 0 0 String
ZOUTPUT 1 Types /SCMTMS/STRING STRING 0 0 0 String
Odata 引用上面结构创建ODATA 服务
重定义
/IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_ENTITY
方法
CREATE_ENTITY 代码:
DATA:ls_data TYPE zcl_ztest_fiori_01_mpc_ext=>ts_zfiori_web.
IF iv_entity_set_name = 'ZFIORI_WEBSet'.
*Transform INPUT REQUEST FROM ODATA-SERVICE into the internal structure
io_data_provider->read_entry_data(
IMPORTING
es_data = ls_data ).
DATA lt_params TYPE TABLE OF rfc_fint_p.
DATA(lv_funcname) = ls_data-ikeyna."函数名
DATA:lv_str_json TYPE string.
lv_str_json = ls_data-ivalue.
zcl_json_handler=>build_params(
EXPORTING
function_name = CONV #( lv_funcname )
IMPORTING
paramtab = DATA(lt_paramtab)
exceptab = DATA(lt_exceptab)
params = lt_params
EXCEPTIONS
invalid_function = 1
unsupported_param_type = 2
).
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
DATA: lo_oexcp TYPE REF TO cx_root.
TRY.
CALL METHOD zcl_json_handler=>json_deserialize
EXPORTING
json = lv_str_json
CHANGING
paramtab = lt_paramtab.
TRY.
CALL FUNCTION lv_funcname
PARAMETER-TABLE lt_paramtab
EXCEPTION-TABLE lt_exceptab.
CATCH cx_root INTO lo_oexcp.
DATA(lv_etext) = lo_oexcp->if_message~get_longtext( preserve_newlines = abap_true ).
MESSAGE lv_etext TYPE 'E'.
ENDTRY.
CATCH cx_root INTO lo_oexcp.
lv_etext = lo_oexcp->if_message~get_text( ).
MESSAGE lv_etext TYPE 'E'.
ENDTRY.
zcl_json_handler=>serialize_json(
EXPORTING
paramtab = lt_paramtab
params = lt_params
IMPORTING
o_string = DATA(o_string)
).
ls_data-zoutput = o_string.
copy_data_to_ref(
EXPORTING
is_data = ls_data
CHANGING
cr_data = er_entity
).
ENDIF.
用的工具类代码:
class ZCL_JSON_HANDLER definition
public
create public .
public section.
type-pools ABAP .
type-pools JS .
*"* public components of class ZCL_JSON_HANDLER
*"* do not include other source files here!!!
interfaces IF_HTTP_EXTENSION .
constants XNL type ABAP_CHAR1 value %_NEWLINE ##NO_TEXT.
constants XCRLF type ABAP_CR_LF value %_CR_LF ##NO_TEXT.
data MY_SERVICE type STRING .
data MY_URL type STRING .
class-methods ABAP2JSON
importing
!ABAP_DATA type DATA
!NAME type STRING optional
!UPCASE type XFELD optional
!CAMELCASE type XFELD optional
!CAMELCASE_NAMES type STRINGTAB optional
returning
value(JSON_STRING) type STRING
exceptions
ERROR_IN_DATA_DESCRIPTION .
class-methods ABAP2PERL
importing
!ABAP_DATA type DATA
!NAME type STRING optional
!UPCASE type XFELD optional
returning
value(PERL_STRING) type STRING
exceptions
ERROR_IN_DATA_DESCRIPTION .
class-methods ABAP2XML
importing
!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
returning
value(XML_STRING) type STRING .
class-methods ABAP2YAML
importing
!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
returning
value(YAML_STRING) type STRING
exceptions
ERROR_IN_DATA_DESCRIPTION .
class-methods BUILD_PARAMS
importing
!FUNCTION_NAME type RS38L_FNAM
exporting
!PARAMTAB type ABAP_FUNC_PARMBIND_TAB
!EXCEPTAB type ABAP_FUNC_EXCPBIND_TAB
!PARAMS type ANY
exceptions
INVALID_FUNCTION
UNSUPPORTED_PARAM_TYPE .
class-methods JSON2ABAP
importing
!JSON_STRING type STRING optional
!VAR_NAME type STRING optional
!PROPERTY_PATH type STRING default 'json_obj'
exporting
value(PROPERTY_TABLE) type JS_PROPERTY_TAB
changing
!JS_OBJECT type ref to CL_JAVA_SCRIPT optional
value(ABAP_DATA) type ANY optional
raising
ZCX_JSON .
class-methods JSON_DESERIALIZE
importing
!JSON type STRING
changing
!PARAMTAB type ABAP_FUNC_PARMBIND_TAB
raising
ZCX_JSON .
methods NOTES
returning
value(TEXT) type STRING .
class-methods SERIALIZE_JSON
importing
!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_TRUE
!CAMELCASE type ABAP_BOOL default ABAP_FALSE
!CAMELCASE_NAMES type STRINGTAB optional
exporting
!O_STRING type STRING .
class-methods SERIALIZE_PERL
importing
!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
exporting
!PERL_STRING type STRING .
class-methods SERIALIZE_XML
importing
!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 optional
exporting
!O_STRING type STRING .
class-methods SERIALIZE_YAML
importing
!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
exporting
!YAML_STRING type STRING .
class-methods DESERIALIZE_ID
importing
!JSON type STRING
changing
!PARAMTAB type ABAP_FUNC_PARMBIND_TAB
raising
ZCX_JSON .
class-methods SERIALIZE_ID
importing
!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
exporting
!O_STRING type STRING
raising
ZCX_JSON .
protected section.
*"* protected components of class ZCL_JSON_HANDLER
*"* do not include other source files here!!!
private section.
*"* private components of class ZCL_JSON_HANDLER
*"* do not include other source files here!!!
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)
* | [--->] CAMELCASE_NAMES TYPE STRINGTAB(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.
data my_camelcase type xfeld.
my_camelcase = camelcase.
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 needs
case &3.
* 1. ABAP numeric types
when 'I'. " Integer
condense &1.
if sign( &1 ) < 0.
shift &1 by 1 places right circular.
endif.
dont_quote = 'X'.
when 'F'. " Float
condense &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'. " Hexadecimal
condense &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 types
when 'D'. " Date type
CONCATENATE &1(4) '-' &1+4(2) '-' &1+6(2) INTO &1.
when 'T'. " Time representation
CONCATENATE &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 chars
replace 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 type
describe 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 start
describe field <abap_data> type l_type components l_comps.
***************************************************
* Tables
***************************************************
if l_type eq cl_abap_typedescr=>typekind_table.
* '[' JSON table opening bracket
append '[' 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 = my_camelcase camelcase_names = camelcase_names ).
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 brace
append '{' 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'.
l_name = to_mixed( val = l_name case = 'a' ).
else.
read table camelcase_names from l_name transporting no fields.
if sy-subrc eq 0.
l_name = to_mixed( val = l_name case = 'a' ).
my_camelcase = 'X'.
else.
my_camelcase = abap_false.
endif.
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 or
s_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 = my_camelcase camelcase_names = camelcase_names ).
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 needs
case &3.
* 1. ABAP numeric types
when 'I'. " Integer
condense &1.
if sign( &1 ) < 0.
shift &1 by 1 places right circular.
endif.
dont_quote = 'X'.
when 'F'. " Float
condense &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'. " Hexadecimal
condense &1.
concatenate '0x' &1 into &1.
dont_quote = 'X'.
* 2. ABAP char types
when 'D'. " Date type
CONCATENATE &1(4) '-' &1+4(2) '-' &1+6(2) INTO &1.
when 'T'. " Time representation
CONCATENATE &1(2) ':' &1+2(2) ':' &1+4(2) INTO &1.
when 'N'. " Numeric te