RESTFUL方式


SE24新建异常类:ZCX_JSON

SE24新建类:ZCL_JSON_HANDLER

 点击基于源代码复制以下代码

   1 class ZCL_JSON_HANDLER definition
   2   public
   3   create public .
   4 
   5 public section.
   6   type-pools ABAP .
   7   type-pools JS .
   8 
   9 *"* public components of class ZCL_JSON_HANDLER
  10 *"* do not include other source files here!!!
  11   interfaces IF_HTTP_EXTENSION .
  12 
  13   constants XNL type ABAP_CHAR1 value %_NEWLINE ##NO_TEXT.
  14   constants XCRLF type ABAP_CR_LF value %_CR_LF ##NO_TEXT.
  15   data MY_SERVICE type STRING .
  16   data MY_URL type STRING .
  17 
  18   class-methods ABAP2JSON
  19     importing
  20       !ABAP_DATA type DATA
  21       !NAME type STRING optional
  22       !UPCASE type XFELD optional
  23       !CAMELCASE type XFELD optional
  24       !CAMELCASE_NAMES type STRINGTAB optional
  25     returning
  26       value(JSON_STRING) type STRING
  27     exceptions
  28       ERROR_IN_DATA_DESCRIPTION .
  29   class-methods ABAP2PERL
  30     importing
  31       !ABAP_DATA type DATA
  32       !NAME type STRING optional
  33       !UPCASE type XFELD optional
  34     returning
  35       value(PERL_STRING) type STRING
  36     exceptions
  37       ERROR_IN_DATA_DESCRIPTION .
  38   class-methods ABAP2XML
  39     importing
  40       !ABAP_DATA type DATA
  41       !NAME type STRING optional
  42       !WITH_XML_HEADER type ABAP_BOOL default ABAP_FALSE
  43       !UPCASE type XFELD optional
  44       !NAME_ATR type STRING optional
  45     returning
  46       value(XML_STRING) type STRING .
  47   class-methods ABAP2YAML
  48     importing
  49       !ABAP_DATA type DATA
  50       !NAME type STRING optional
  51       !UPCASE type XFELD optional
  52       !Y_LEVEL type I default 0
  53       !S_INDEX type I default 0
  54       !FIRST_ROW type XFELD optional
  55       !DONT_INDENT type XFELD optional
  56     returning
  57       value(YAML_STRING) type STRING
  58     exceptions
  59       ERROR_IN_DATA_DESCRIPTION .
  60   class-methods BUILD_PARAMS
  61     importing
  62       !FUNCTION_NAME type RS38L_FNAM
  63     exporting
  64       !PARAMTAB type ABAP_FUNC_PARMBIND_TAB
  65       !EXCEPTAB type ABAP_FUNC_EXCPBIND_TAB
  66       !PARAMS type ANY
  67     exceptions
  68       INVALID_FUNCTION
  69       UNSUPPORTED_PARAM_TYPE .
  70   class-methods JSON2ABAP
  71     importing
  72       !JSON_STRING type STRING optional
  73       !VAR_NAME type STRING optional
  74       !PROPERTY_PATH type STRING default 'json_obj'
  75     exporting
  76       value(PROPERTY_TABLE) type JS_PROPERTY_TAB
  77     changing
  78       !JS_OBJECT type ref to CL_JAVA_SCRIPT optional
  79       value(ABAP_DATA) type ANY optional
  80     raising
  81       ZCX_JSON .
  82   class-methods JSON_DESERIALIZE
  83     importing
  84       !JSON type STRING
  85     changing
  86       !PARAMTAB type ABAP_FUNC_PARMBIND_TAB
  87     raising
  88       ZCX_JSON .
  89   methods NOTES
  90     returning
  91       value(TEXT) type STRING .
  92   class-methods SERIALIZE_JSON
  93     importing
  94       !PARAMTAB type ABAP_FUNC_PARMBIND_TAB
  95       !PARAMS type ANY optional
  96       !EXCEPTAB type ABAP_FUNC_EXCPBIND_TAB optional
  97       !SHOW_IMPP type ABAP_BOOL optional
  98       !JSONP type STRING optional
  99       !LOWERCASE type ABAP_BOOL default ABAP_TRUE
 100       !CAMELCASE type ABAP_BOOL default ABAP_FALSE
 101       !CAMELCASE_NAMES type STRINGTAB optional
 102     exporting
 103       !O_STRING type STRING .
 104   class-methods SERIALIZE_PERL
 105     importing
 106       !PARAMTAB type ABAP_FUNC_PARMBIND_TAB
 107       !PARAMS type ANY optional
 108       !EXCEPTAB type ABAP_FUNC_EXCPBIND_TAB optional
 109       !SHOW_IMPP type ABAP_BOOL optional
 110       !JSONP type STRING optional
 111       !LOWERCASE type ABAP_BOOL default ABAP_FALSE
 112       !FUNCNAME type RS38L_FNAM
 113     exporting
 114       !PERL_STRING type STRING .
 115   class-methods SERIALIZE_XML
 116     importing
 117       !PARAMTAB type ABAP_FUNC_PARMBIND_TAB
 118       !PARAMS type ANY optional
 119       !EXCEPTAB type ABAP_FUNC_EXCPBIND_TAB optional
 120       !SHOW_IMPP type ABAP_BOOL optional
 121       !JSONP type STRING optional
 122       !FUNCNAME type RS38L_FNAM
 123       !LOWERCASE type ABAP_BOOL default ABAP_FALSE
 124       !FORMAT type STRING optional
 125     exporting
 126       !O_STRING type STRING .
 127   class-methods SERIALIZE_YAML
 128     importing
 129       !PARAMTAB type ABAP_FUNC_PARMBIND_TAB
 130       !PARAMS type ANY optional
 131       !EXCEPTAB type ABAP_FUNC_EXCPBIND_TAB optional
 132       !SHOW_IMPP type ABAP_BOOL optional
 133       !JSONP type STRING optional
 134       !LOWERCASE type ABAP_BOOL default ABAP_FALSE
 135     exporting
 136       !YAML_STRING type STRING .
 137   class-methods DESERIALIZE_ID
 138     importing
 139       !JSON type STRING
 140     changing
 141       !PARAMTAB type ABAP_FUNC_PARMBIND_TAB
 142     raising
 143       ZCX_JSON .
 144   class-methods SERIALIZE_ID
 145     importing
 146       !PARAMTAB type ABAP_FUNC_PARMBIND_TAB
 147       !PARAMS type ANY optional
 148       !EXCEPTAB type ABAP_FUNC_EXCPBIND_TAB optional
 149       !SHOW_IMPP type ABAP_BOOL optional
 150       !JSONP type STRING optional
 151       !LOWERCASE type ABAP_BOOL default ABAP_FALSE
 152       !FORMAT type STRING default 'JSON'
 153       !FUNCNAME type RS38L_FNAM optional
 154       !CAMELCASE type ABAP_BOOL default ABAP_FALSE
 155     exporting
 156       !O_STRING type STRING
 157     raising
 158       ZCX_JSON .
 159 protected section.
 160 *"* protected components of class ZCL_JSON_HANDLER
 161 *"* do not include other source files here!!!
 162 private section.
 163 *"* private components of class ZCL_JSON_HANDLER
 164 *"* do not include other source files here!!!
 165 ENDCLASS.
 166 
 167 
 168 
 169 CLASS ZCL_JSON_HANDLER IMPLEMENTATION.
 170 
 171 
 172 * ---------------------------------------------------------------------------------------+
 173 * | Static Public Method ZCL_JSON_HANDLER=>ABAP2JSON
 174 * +-------------------------------------------------------------------------------------------------+
 175 * | [--->] ABAP_DATA                      TYPE        DATA
 176 * | [--->] NAME                           TYPE        STRING(optional)
 177 * | [--->] UPCASE                         TYPE        XFELD(optional)
 178 * | [--->] CAMELCASE                      TYPE        XFELD(optional)
 179 * | [--->] CAMELCASE_NAMES                TYPE        STRINGTAB(optional)
 180 * | [<-()] JSON_STRING                    TYPE        STRING
 181 * | [EXC!] ERROR_IN_DATA_DESCRIPTION
 182 * +--------------------------------------------------------------------------------------
 183 method abap2json.
 184 */**********************************************/*
 185 */ This method takes any ABAP data variable and /*
 186 */ returns a string representing its value in   /*
 187 */ JSON format.                                 /*
 188 */ ABAP references are always de-referenced and /*
 189 */ treated as normal variables.                 /*
 190 */**********************************************/*
 191 
 192   type-pools: abap.
 193 
 194   constants:
 195     c_comma type c value ',',
 196     c_colon type c value ':',
 197     c_quote type c value '"'.
 198 
 199   data:
 200     dont_quote      type xfeld,
 201     json_fragments  type table of string,
 202     rec_json_string type string,
 203     l_type          type c,
 204     s_type          type c,
 205     l_comps         type i,
 206     l_lines         type i,
 207     l_index         type i,
 208     l_value         type string,
 209     l_name          type string,
 210     l_strudescr     type ref to cl_abap_structdescr.
 211 
 212   field-symbols:
 213      type any,
 214           type any table,
 215           type any table,
 216           type any,
 217       type abap_compdescr.
 218 
 219   data   my_camelcase    type xfeld.
 220   my_camelcase = camelcase.
 221 
 222   define get_scalar_value.
 223     " &1 : assigned var
 224     " &2 : abap data
 225     " &3 : abap type
 226     &1 = &2.
 227 ****************************************************
 228 * Adapt some basic ABAP types (pending inclusion of all basic abap types?)
 229 * Feel free to customize this for your needs
 230     case &3.
 231 *       1. ABAP numeric types
 232       when 'I'. " Integer
 233         condense &1.
 234         if sign( &1 ) < 0.
 235           shift &1 by 1 places right circular.
 236         endif.
 237         dont_quote = 'X'.
 238 
 239       when 'F'. " Float
 240         condense &1.
 241         dont_quote = 'X'.
 242 
 243       when 'P'. " Packed number (used in quantities or currency, for example)
 244         condense &1.
 245         if sign( &1 ) < 0.
 246           shift &1 by 1 places right circular.
 247         endif.
 248         dont_quote = 'X'.
 249 
 250       when 'X'. " Hexadecimal
 251         condense &1.
 252         concatenate '0x' &1 into &1.
 253 *        dont_quote = 'X'.
 254 *        "Quote it, as JSON doesn't support Hex or Octal as native types.
 255 
 256 *       2. ABAP char types
 257       when 'D'. " Date type
 258         CONCATENATE &1(4) '-' &1+4(2) '-' &1+6(2) INTO &1.
 259 
 260       when 'T'. " Time representation
 261         CONCATENATE &1(2) ':' &1+2(2) ':' &1+4(2) INTO &1.
 262 
 263       when 'N'. " Numeric text field
 264 *           condense &1.
 265 
 266       when 'C' or 'g'. " Char sequences and Strings
 267 * Put safe chars
 268         replace all occurrences of '\' in &1 with '\\' .
 269         replace all occurrences of '"' in &1 with '\"' .
 270         replace all occurrences of cl_abap_char_utilities=>cr_lf in &1 with '\r\n' .
 271         replace all occurrences of cl_abap_char_utilities=>newline in &1 with '\n' .
 272         replace all occurrences of cl_abap_char_utilities=>horizontal_tab in &1 with '\t' .
 273         replace all occurrences of cl_abap_char_utilities=>backspace in &1 with '\b' .
 274         replace all occurrences of cl_abap_char_utilities=>form_feed in &1 with '\f' .
 275 
 276       when 'y'.  " XSTRING
 277 * Put the XSTRING in Base64
 278         &1 = cl_http_utility=>ENCODE_X_BASE64( &2 ).
 279 
 280       when others.
 281 * Don't hesitate to add and modify scalar abap types to suit your taste.
 282 
 283     endcase.
 284 ** End of scalar data preparing.
 285 
 286 * Enclose value in quotes (or not)
 287     if dont_quote ne 'X'.
 288       concatenate c_quote &1 c_quote into &1.
 289     endif.
 290 
 291     clear dont_quote.
 292 
 293   end-of-definition.
 294 
 295 
 296 ***************************************************
 297 *  Prepare field names, JSON does quote names!!   *
 298 *  You must be strict in what you produce.        *
 299 ***************************************************
 300   if name is not initial.
 301     concatenate c_quote name c_quote c_colon into rec_json_string.
 302     append rec_json_string to json_fragments.
 303     clear rec_json_string.
 304   endif.
 305 
 306 **
 307 * Get ABAP data type
 308   describe field abap_data type l_type components l_comps.
 309 
 310 ***************************************************
 311 *  Get rid of data references
 312 ***************************************************
 313   if l_type eq cl_abap_typedescr=>typekind_dref.
 314     assign abap_data->* to .
 315     if sy-subrc ne 0.
 316       append '{}' to json_fragments.
 317       concatenate lines of json_fragments into json_string.
 318       exit.
 319     endif.
 320   else.
 321     assign abap_data to .
 322   endif.
 323 
 324 * Get ABAP data type again and start
 325   describe field  type l_type components l_comps.
 326 
 327 ***************************************************
 328 *  Tables
 329 ***************************************************
 330   if l_type eq cl_abap_typedescr=>typekind_table.
 331 * '[' JSON table opening bracket
 332     append '[' to json_fragments.
 333     assign  to .
 334     l_lines = lines(  ).
 335     loop at  assigning .
 336       add 1 to l_index.
 337 *> Recursive call for each table row:
 338       rec_json_string = abap2json( abap_data =  upcase = upcase camelcase = my_camelcase camelcase_names = camelcase_names ).
 339       append rec_json_string to json_fragments.
 340       clear rec_json_string.
 341       if l_index < l_lines.
 342         append c_comma to json_fragments.
 343       endif.
 344     endloop.
 345     append ']' to json_fragments.
 346 * ']' JSON table closing bracket
 347 
 348 
 349 ***************************************************
 350 *  Structures
 351 ***************************************************
 352   else.
 353     if l_comps is not initial.
 354 * '{' JSON object opening curly brace
 355       append '{' to json_fragments.
 356       l_strudescr ?= cl_abap_typedescr=>describe_by_data(  ).
 357       loop at l_strudescr->components assigning .
 358         l_index = sy-tabix .
 359         assign component -name of structure  to .
 360         l_name = -name.
 361 ** ABAP names are usually in caps, set upcase to avoid the conversion to lower case.
 362         if upcase ne 'X'.
 363           " translate l_name to lower case.
 364           l_name = to_lower( l_name ).
 365         endif.
 366         if camelcase eq 'X'.
 367           l_name = to_mixed( val = l_name  case = 'a' ).
 368         else.
 369           read table camelcase_names from l_name transporting no fields.
 370           if sy-subrc eq 0.
 371             l_name = to_mixed( val = l_name  case = 'a' ).
 372             my_camelcase = 'X'.
 373           else.
 374             my_camelcase = abap_false.
 375           endif.
 376         endif.
 377         describe field  type s_type.
 378         if s_type eq cl_abap_typedescr=>typekind_table or s_type eq cl_abap_typedescr=>typekind_dref or
 379            s_type eq cl_abap_typedescr=>typekind_struct1 or s_type eq cl_abap_typedescr=>typekind_struct2.
 380 *> Recursive call for non-scalars:
 381           rec_json_string = abap2json( abap_data =  name = l_name upcase = upcase camelcase = my_camelcase camelcase_names = camelcase_names ).
 382         else.
 383           if s_type eq cl_abap_typedescr=>typekind_oref or s_type eq cl_abap_typedescr=>typekind_iref.
 384             rec_json_string = '"REF UNSUPPORTED"'.
 385           else.
 386             get_scalar_value rec_json_string  s_type.
 387           endif.
 388           concatenate c_quote l_name c_quote c_colon rec_json_string into rec_json_string.
 389         endif.
 390         append rec_json_string to json_fragments.
 391         clear rec_json_string. clear l_name.
 392         if l_index < l_comps.
 393           append c_comma to json_fragments.
 394         endif.
 395       endloop.
 396       append '}' to json_fragments.
 397 * '}' JSON object closing curly brace
 398 
 399 
 400 ****************************************************
 401 *                  - Scalars -                     *
 402 ****************************************************
 403     else.
 404       get_scalar_value l_value  l_type.
 405       append l_value to json_fragments.
 406 
 407     endif.
 408 * End of structure/scalar IF block.
 409 ***********************************
 410 
 411   endif.
 412 * End of main IF block.
 413 **********************
 414 
 415 * Use a loop in older releases that don't support concatenate lines.
 416   concatenate lines of json_fragments into json_string.
 417 
 418 endmethod.
 419 
 420 
 421 * ---------------------------------------------------------------------------------------+
 422 * | Static Public Method ZCL_JSON_HANDLER=>ABAP2PERL
 423 * +-------------------------------------------------------------------------------------------------+
 424 * | [--->] ABAP_DATA                      TYPE        DATA
 425 * | [--->] NAME                           TYPE        STRING(optional)
 426 * | [--->] UPCASE                         TYPE        XFELD(optional)
 427 * | [<-()] PERL_STRING                    TYPE        STRING
 428 * | [EXC!] ERROR_IN_DATA_DESCRIPTION
 429 * +--------------------------------------------------------------------------------------
 430 method ABAP2PERL.
 431 */**********************************************/*
 432 */ This method takes any ABAP data variable and /*
 433 */ returns a string representing its value in   /*
 434 */ Perl Data::Dumper format, ready to be evaled /*
 435 */ in a Perl program.                           /*
 436 */**********************************************/*
 437 
 438   type-pools: abap.
 439 
 440   constants:
 441     c_comma type c value ',',
 442     c_colon type c value ':',
 443     c_quote type c value ''''.
 444 
 445   data:
 446     perl_hash_assign type string,
 447     dont_quote type xfeld,
 448     perl_fragments type table of string,
 449     rec_perl_string type string,
 450     l_type  type c,
 451     s_type  type c,
 452     l_comps type i,
 453     l_lines type i,
 454     l_index type i,
 455     l_value type string,
 456     l_name  type string,
 457     l_typedescr type ref to cl_abap_structdescr.
 458 
 459   field-symbols:
 460      type any,
 461      type any table,
 462      type any table,
 463      type any,
 464      type abap_compdescr.
 465 
 466   concatenate space '=>' space into perl_hash_assign respecting blanks.
 467 
 468   define get_scalar_value.
 469     " &1 : assigned var
 470     " &2 : abap data
 471     " &3 : abap type
 472     &1 = &2.
 473 ****************************************************
 474 * Adapt some basic ABAP types (pending inclusion of all basic abap types?)
 475 * Feel free to customize this for your needs
 476     case &3.
 477 *       1. ABAP numeric types
 478       when 'I'. " Integer
 479         condense &1.
 480         if sign( &1 ) < 0.
 481           shift &1 by 1 places right circular.
 482         endif.
 483         dont_quote = 'X'.
 484 
 485       when 'F'. " Float
 486         condense &1.
 487         dont_quote = 'X'.
 488 
 489       when 'P'. " Packed number (used in quantities, for example)
 490         condense &1.
 491         if sign( &1 ) < 0.
 492           shift &1 by 1 places right circular.
 493         endif.
 494         dont_quote = 'X'.
 495 
 496       when 'X'. " Hexadecimal
 497         condense &1.
 498         concatenate '0x' &1 into &1.
 499         dont_quote = 'X'.
 500 
 501 *       2. ABAP char types
 502       when 'D'. " Date type
 503         CONCATENATE &1(4) '-' &1+4(2) '-' &1+6(2) INTO &1.
 504 
 505       when 'T'. " Time representation
 506         CONCATENATE &1(2) ':' &1+2(2) ':' &1+4(2) INTO &1.
 507 
 508       when 'N'. " Numeric text field
 509 *           condense &1.
 510 
 511       when 'C' or 'g'. " Char sequences and Strings
 512 * Put safe chars
 513         replace all occurrences of '''' in &1 with '\''' .
 514 
 515       when 'y'.  " XSTRING
 516 * Put the XSTRING in Base64
 517         &1 = cl_http_utility=>ENCODE_X_BASE64( &2 ).
 518 
 519       when others.
 520 * Don't hesitate to add and modify abap types to suit your taste.
 521 
 522     endcase.
 523 ** End of scalar data preparing.
 524 
 525 * Enclose value in quotes (or not)
 526     if dont_quote ne 'X'.
 527       concatenate c_quote &1 c_quote into &1.
 528     endif.
 529     clear dont_quote.
 530 
 531   end-of-definition.
 532 
 533 
 534 
 535 ***************************************************
 536 *  Prepare field names, we use single quotes.     *
 537 *  You must be strict in what you produce.        *
 538 ***************************************************
 539   if name is not initial.
 540     concatenate c_quote name c_quote perl_hash_assign into rec_perl_string respecting blanks.
 541     append rec_perl_string to perl_fragments.
 542     clear rec_perl_string.
 543   endif.
 544 
 545 **
 546 * Get ABAP data type
 547   describe field abap_data type l_type components l_comps.
 548 
 549 ***************************************************
 550 *  Get rid of data references
 551 ***************************************************
 552   if l_type eq cl_abap_typedescr=>typekind_dref.
 553     assign abap_data->* to .
 554     if sy-subrc ne 0.
 555       append '{}' to perl_fragments.
 556       concatenate lines of perl_fragments into perl_string.
 557       exit.
 558     endif.
 559   else.
 560     assign abap_data to .
 561   endif.
 562 
 563 
 564 * Get ABAP data type again and start
 565   describe field  type l_type components l_comps.
 566 
 567 ***************************************************
 568 *  Tables
 569 ***************************************************
 570   if l_type eq cl_abap_typedescr=>typekind_table.
 571 * '[' Table opening bracket
 572     append '[' to perl_fragments.
 573     assign  to .
 574     l_lines = lines(  ).
 575     loop at  assigning .
 576       add 1 to l_index.
 577 *> Recursive call here
 578       rec_perl_string = abap2perl( abap_data =  upcase = upcase ).
 579       append rec_perl_string to perl_fragments.
 580       clear rec_perl_string.
 581       if l_index < l_lines.
 582         append c_comma to perl_fragments.
 583       endif.
 584     endloop.
 585     append ']' to perl_fragments.
 586 * ']' Table closing bracket
 587 
 588 
 589 ***************************************************
 590 *  Structures
 591 ***************************************************
 592   else .
 593     if l_comps is not initial.
 594 * '{' Object opening curly brace
 595       append '{' to perl_fragments .
 596       l_typedescr ?= cl_abap_typedescr=>describe_by_data(  ) .
 597       loop at l_typedescr->components assigning  .
 598         l_index = sy-tabix .
 599         assign component -name of structure  to .
 600         l_name = -name.
 601 ** ABAP names are usually in caps, set upcase to avoid the conversion to lower case.
 602         if upcase ne 'X'.
 603           translate l_name to lower case.
 604         endif.
 605         describe field  type s_type.
 606         if s_type eq cl_abap_typedescr=>typekind_table or s_type eq cl_abap_typedescr=>typekind_dref or
 607            s_type eq cl_abap_typedescr=>typekind_struct1 or s_type eq cl_abap_typedescr=>typekind_struct2.
 608 *> Recursive call for non-scalars:
 609           rec_perl_string = abap2perl( abap_data =  name = l_name upcase = upcase ).
 610         else.
 611           if s_type eq cl_abap_typedescr=>TYPEKIND_OREF or s_type eq cl_abap_typedescr=>TYPEKIND_IREF.
 612             rec_perl_string = '"REF UNSUPPORTED"'.
 613           else.
 614             get_scalar_value rec_perl_string  s_type.
 615           endif.
 616           concatenate c_quote l_name c_quote perl_hash_assign rec_perl_string into rec_perl_string.
 617         endif.
 618 
 619         append rec_perl_string to perl_fragments.
 620         clear rec_perl_string.
 621         if l_index < l_comps.
 622           append c_comma to perl_fragments.
 623         endif.
 624       endloop.
 625       append '}' to perl_fragments.
 626 * '}' Object closing curly brace
 627 
 628 
 629 ****************************************************
 630 *                  - Scalars -                     *
 631 ****************************************************
 632     else.
 633 
 634       get_scalar_value l_value  l_type.
 635       append l_value to perl_fragments.
 636 
 637     endif.
 638 * End of structure/scalar IF block.
 639 ***********************************
 640 
 641 
 642   endif.
 643 * End of main IF block.
 644 **********************
 645 
 646 
 647 * Use a loop in older releases that don't support concatenate lines.
 648   concatenate lines of perl_fragments into perl_string.
 649 
 650 endmethod.
 651 
 652 
 653 * ---------------------------------------------------------------------------------------+
 654 * | Static Public Method ZCL_JSON_HANDLER=>ABAP2XML
 655 * +-------------------------------------------------------------------------------------------------+
 656 * | [--->] ABAP_DATA                      TYPE        DATA
 657 * | [--->] NAME                           TYPE        STRING(optional)
 658 * | [--->] WITH_XML_HEADER                TYPE        ABAP_BOOL (default =ABAP_FALSE)
 659 * | [--->] UPCASE                         TYPE        XFELD(optional)
 660 * | [--->] NAME_ATR                       TYPE        STRING(optional)
 661 * | [<-()] XML_STRING                     TYPE        STRING
 662 * +--------------------------------------------------------------------------------------
 663 method ABAP2XML.
 664 *
 665 */ Look at method serialize_id for a new way of doing XML.
 666 
 667   type-pools: abap.
 668 
 669   constants:
 670     xml_head type string value '<?xml version="1.0" encoding="utf-8"?>',
 671     item_atr type string value 'idx="#"'.
 672 
 673   data:
 674     xml_fragments type table of string,
 675     rec_xml_string type string,
 676     l_type  type c,
 677     s_type  type c,
 678     l_comps type i,
 679     l_value type string,
 680     t_string type string,
 681     l_item_atr type string,
 682     l_item_str type string,
 683     l_name type string,
 684     l_idx type string,
 685     l_typedescr type ref to cl_abap_structdescr,
 686     l_linedescr type ref to cl_abap_datadescr,
 687     l_tabledescr type ref to cl_abap_tabledescr.
 688 
 689   field-symbols:
 690      type any,
 691      type any table,
 692      type any table,
 693      type any,
 694      type abap_compdescr.
 695 
 696   define get_scalar_value.
 697     " &1 : assigned var
 698     " &2 : abap data
 699     " &3 : abap type
 700     &1 = &2.
 701 ****************************************************
 702 * Adapt some basic ABAP types (pending inclusion of all basic abap types?)
 703 * Feel free to customize this for your needs
 704     case &3.
 705 *       1. ABAP numeric types
 706       when 'I'. " Integer
 707         condense &1.
 708         if sign( &1 ) < 0.
 709           shift &1 by 1 places right circular.
 710         endif.
 711 
 712       when 'F'. " Float
 713         condense &1.
 714 
 715       when 'P'. " Packed number (used in quantities, for example)
 716         condense &1.
 717         if sign( &1 ) < 0.
 718           shift &1 by 1 places right circular.
 719         endif.
 720 
 721       when 'X'. " Hexadecimal
 722         condense &1.
 723         concatenate '0x' &1 into &1.
 724 
 725 *       2. ABAP char types
 726       when 'D'. " Date type
 727         CONCATENATE &1(4) '-' &1+4(2) '-' &1+6(2) INTO &1.
 728 
 729       when 'T'. " Time representation
 730         CONCATENATE &1(2) ':' &1+2(2) ':' &1+4(2) INTO &1.
 731 
 732       when 'N'. " Numeric text field
 733 *           condense &1.
 734 
 735       when 'C' or 'g'. " Char sequences and Strings
 736 * Put safe chars
 737         t_string = &2.
 738         &1 = cl_http_utility=>escape_html( t_string ).
 739 
 740       when 'y'.  " XSTRING
 741 * Put the XSTRING in Base64
 742         &1 = cl_http_utility=>ENCODE_X_BASE64( &2 ).
 743 
 744       when others.
 745 * Don't hesitate to add and modify abap types to suit your taste.
 746 
 747     endcase.
 748 ** End of scalar data preparing.
 749 
 750   end-of-definition.
 751 
 752 
 753 
 754 *******************************
 755 * Put XML header if requested *
 756 *******************************
 757   if with_xml_header eq abap_true.
 758     append xml_head to xml_fragments.
 759   endif.
 760 
 761 ***************************************************
 762 *  Open XML tag                                   *
 763 *  <          >                                   *
 764 ***************************************************
 765   if name is not initial.
 766     l_name = name.
 767     if name_atr is not initial.
 768       concatenate name name_atr into l_name separated by space.
 769     endif.
 770     concatenate '<' l_name '>' into rec_xml_string.
 771     append rec_xml_string to xml_fragments.
 772     clear rec_xml_string.
 773   endif.
 774 
 775 **
 776 * Get ABAP data type
 777   describe field abap_data type l_type components l_comps .
 778 
 779 ***************************************************
 780 *  Get rid of data references
 781 ***************************************************
 782   if l_type eq cl_abap_typedescr=>typekind_dref.
 783     assign abap_data->* to .
 784     if sy-subrc ne 0.
 785       if name is not initial.
 786         concatenate '<' name '/>' into xml_string.
 787       else.
 788         clear xml_string.
 789       endif.
 790       exit.
 791     endif.
 792   else.
 793     assign abap_data to .
 794   endif.
 795 
 796 
 797 * Get ABAP data type again and start
 798   describe field  type l_type components l_comps.
 799 
 800 
 801 ***************************************************
 802 *  Tables
 803 ***************************************************
 804   if l_type eq cl_abap_typedescr=>typekind_table.
 805     l_tabledescr ?= cl_abap_typedescr=>describe_by_data(  ).
 806     l_linedescr = l_tabledescr->get_table_line_type( ).
 807     l_item_str = l_linedescr->get_relative_name( ).
 808     assign  to .
 809     loop at  assigning .
 810       l_idx = sy-tabix.
 811       condense l_idx.
 812       l_item_atr = item_atr.
 813       replace '#' in l_item_atr with l_idx.
 814       if upcase ne 'X'.
 815         translate l_item_str to lower case.
 816       endif.
 817 *> Recursive call for line items here:
 818       rec_xml_string = abap2xml( abap_data =  upcase = upcase name = l_item_str name_atr = l_item_atr ).
 819       append rec_xml_string to xml_fragments.
 820       clear rec_xml_string.
 821     endloop.
 822 
 823 
 824 ***************************************************
 825 *  Structures
 826 ***************************************************
 827   else .
 828     if l_comps is not initial.
 829       l_typedescr ?= cl_abap_typedescr=>describe_by_data(  ).
 830       loop at l_typedescr->components assigning  .
 831         assign component -name of structure  to .
 832         l_name = -name. " l_value justs holds the name here.
 833 ** ABAP names are usually in caps, set upcase to avoid the conversion to lower case.
 834         if upcase ne 'X'.
 835           translate l_name to lower case.
 836         endif.
 837         describe field  type s_type.
 838         if s_type eq cl_abap_typedescr=>typekind_table or s_type eq cl_abap_typedescr=>typekind_dref or
 839            s_type eq cl_abap_typedescr=>typekind_struct1 or s_type eq cl_abap_typedescr=>typekind_struct2.
 840 *> Recursive call for non-scalars:
 841           rec_xml_string = abap2xml( abap_data =  name = l_name upcase = upcase ).
 842         else.
 843           if s_type eq cl_abap_typedescr=>TYPEKIND_OREF or s_type eq cl_abap_typedescr=>TYPEKIND_IREF.
 844             rec_xml_string = 'REF UNSUPPORTED'.
 845           else.
 846             get_scalar_value rec_xml_string  s_type.
 847           endif.
 848           concatenate '<' l_name '>' rec_xml_string '' l_name '>' into rec_xml_string.
 849         endif.
 850         append rec_xml_string to xml_fragments.
 851         clear rec_xml_string.
 852       endloop.
 853 
 854 
 855 
 856 ****************************************************
 857 *                  - Scalars -                     *
 858 ****************************************************
 859     else.
 860 
 861       get_scalar_value l_value  l_type.
 862       append l_value to xml_fragments.
 863 
 864     endif.
 865 * End of structure/scalar IF block.
 866 ***********************************
 867 
 868 
 869   endif.
 870 * End of main IF block.
 871 **********************
 872 
 873 
 874 *****************
 875 * Close XML tag *
 876 *****************
 877   if name is not initial.
 878     concatenate '' name '>' into rec_xml_string.
 879     append rec_xml_string to xml_fragments.
 880     clear rec_xml_string.
 881   endif.
 882 
 883 * Use a loop in older releases that don't support concatenate lines.
 884   concatenate lines of xml_fragments into xml_string.
 885 
 886 endmethod.
 887 
 888 
 889 * ---------------------------------------------------------------------------------------+
 890 * | Static Public Method ZCL_JSON_HANDLER=>ABAP2YAML
 891 * +-------------------------------------------------------------------------------------------------+
 892 * | [--->] ABAP_DATA                      TYPE        DATA
 893 * | [--->] NAME                           TYPE        STRING(optional)
 894 * | [--->] UPCASE                         TYPE        XFELD(optional)
 895 * | [--->] Y_LEVEL                        TYPE        I (default =0)
 896 * | [--->] S_INDEX                        TYPE        I (default =0)
 897 * | [--->] FIRST_ROW                      TYPE        XFELD(optional)
 898 * | [--->] DONT_INDENT                    TYPE        XFELD(optional)
 899 * | [<-()] YAML_STRING                    TYPE        STRING
 900 * | [EXC!] ERROR_IN_DATA_DESCRIPTION
 901 * +--------------------------------------------------------------------------------------
 902 method ABAP2YAML.
 903 *********************
 904 * ABAP goes to YAML *
 905 *********************
 906 
 907   type-pools: abap.
 908 
 909   constants:
 910     c_comma     type c value ',',
 911     c_space     type c value ' ',
 912     c_colon     type c value ':',
 913     c_quote     type c value '"',
 914     c_squot     type c value '''',
 915     c_colo2(2)  type c value ': ',
 916     c_indt2     type i value 2,
 917     c_hyph      type c value '-'.
 918 
 919   data:
 920   ly_level type i,
 921   l_dont_indent type xfeld,
 922   dec_level type i value 0,
 923   dont_quote type xfeld,
 924   yaml_fragments type table of string,
 925   rec_yaml_string type string,
 926   l_type  type c ,
 927   l_comps type i ,
 928   l_lines type i ,
 929   l_index type i ,
 930   l_value type string,
 931   l_name type string.
 932   field-symbols:
 933      type any,
 934      type any table,
 935      type any table,
 936      type any.
 937   data l_typedescr type ref to cl_abap_structdescr .
 938   field-symbols  type abap_compdescr .
 939 
 940   ly_level = y_level.
 941 
 942 **
 943 * Get ABAP data type
 944   describe field abap_data type l_type components l_comps .
 945 
 946 ***************************************************
 947 *  First of all, get rid of data references
 948 ***************************************************
 949   if l_type eq cl_abap_typedescr=>typekind_dref.
 950     assign abap_data->* to .
 951     if sy-subrc ne 0.
 952       yaml_string = space. " pasamos de poner nada si falla...
 953       exit.
 954     endif.
 955   else.
 956     assign abap_data to .
 957   endif.
 958 
 959 
 960 * Get ABAP data type again and start
 961   describe field  type l_type components l_comps.
 962 
 963 ***************************************************
 964 *  Prepare field names, YAML does not quote names *
 965 ***************************************************
 966 * Put hyphens...
 967   if name is initial and y_level gt 0.
 968     concatenate c_hyph space into rec_yaml_string respecting blanks.
 969     l_dont_indent = 'X'.
 970   endif.
 971 
 972   if name is not initial.
 973     concatenate name c_colon c_space into rec_yaml_string respecting blanks.
 974   endif.
 975 
 976 * do indent
 977   if dont_indent ne 'X'.
 978     do  ly_level  times.
 979       shift rec_yaml_string right by c_indt2 places.
 980     enddo.
 981   endif.
 982 
 983   append rec_yaml_string to yaml_fragments.
 984   clear rec_yaml_string.
 985 
 986 
 987 
 988 
 989 ***************************************************
 990 *  Tables
 991 ***************************************************
 992   if l_type eq cl_abap_typedescr=>TYPEKIND_TABLE.
 993     assign  to .
 994     l_lines = lines(  ).
 995     clear l_index.
 996     if l_lines eq 0.
 997       move '[]' to rec_yaml_string.
 998       append rec_yaml_string to yaml_fragments.
 999       clear rec_yaml_string.
1000       append xnl to yaml_fragments.
1001     else.
1002       if name is not initial.
1003         append xnl to yaml_fragments.
1004       endif.
1005       add 1 to ly_level.
1006       loop at  assigning .
1007         add 1 to l_index.
1008 *> Recursive call here
1009         rec_yaml_string = abap2yaml( abap_data =  upcase = upcase y_level = ly_level s_index = l_index ).
1010         append rec_yaml_string to yaml_fragments.
1011         clear rec_yaml_string.
1012       endloop.
1013     endif.
1014 * YAML table ends *
1015 *******************
1016 
1017 
1018 ***************************************************
1019 *  Structures
1020 ***************************************************
1021   else .
1022     if l_comps is not initial.
1023       if name is not initial.
1024         append xnl to yaml_fragments.
1025       endif.
1026       add 1 to ly_level.
1027 * Loop for structure elements
1028       l_typedescr ?= cl_abap_typedescr=>describe_by_data(  ) .
1029       clear l_index.
1030       loop at l_typedescr->components assigning .
1031         add 1 to l_index.
1032         assign component -name of structure  to .
1033         l_name = -name.
1034 ** ABAP names are usually in caps, set upcase to avoid the conversion to lower case.
1035         if upcase ne 'X'.
1036           translate l_name to lower case.
1037         endif.
1038 *> Recursive call here
1039         rec_yaml_string = abap2yaml( abap_data =  name = l_name upcase = upcase y_level = ly_level s_index = l_index dont_indent = l_dont_indent ).
1040         clear l_dont_indent. " it is only used once
1041         append rec_yaml_string to yaml_fragments.
1042         clear rec_yaml_string.
1043       endloop.
1044 
1045 * YAML structure ends *
1046 ***********************
1047 
1048 
1049 ***************************************************
1050 *  Scalars and others...
1051 ***************************************************
1052     else.
1053       if l_type eq cl_abap_typedescr=>TYPEKIND_OREF or l_type eq cl_abap_typedescr=>TYPEKIND_IREF.
1054         l_value = 'REF UNSUPPORTED'.
1055       else.
1056         l_value = .
1057       endif.
1058 
1059 * Adapt some basic ABAP types (pending inclusion of all basic abap types)
1060 * Feel free to customize this for your needs
1061       case l_type.
1062 *       1. ABAP numeric types
1063         when 'I'. " Integer
1064           condense l_value.
1065           if sign( l_value ) < 0.
1066             shift l_value by 1 places right circular.
1067           endif.
1068           dont_quote = 'X'.
1069 
1070         when 'F'. " Float
1071           condense l_value.
1072           dont_quote = 'X'.
1073 
1074         when 'P'. " Packed number (used in quantities, for example)
1075           condense l_value.
1076           if sign( l_value ) < 0.
1077             shift l_value by 1 places right circular.
1078           endif.
1079           dont_quote = 'X'.
1080 
1081         when 'X'. " Hexadecimal
1082           condense l_value.
1083           concatenate '0x' l_value into l_value.
1084           dont_quote = 'X'.
1085 
1086 *       2. ABAP char types
1087         when 'D'. " Date type
1088           CONCATENATE l_value(4) '-' l_value+4(2) '-' l_value+6(2) INTO l_value.
1089 
1090         when 'T'. " Time representation
1091           CONCATENATE l_value(2) ':' l_value+2(2) ':' l_value+4(2) INTO l_value.
1092 
1093         when 'N'. " Numeric text field
1094 *           condense l_value.
1095 
1096         when 'C' or 'g'. " Chars and Strings
1097 * Put safe chars
1098           replace all occurrences of '\' in l_value with '\\' .
1099           replace all occurrences of '"' in l_value with '\"' .
1100           replace all occurrences of cl_abap_char_utilities=>cr_lf in l_value with '\r\n' .
1101           replace all occurrences of cl_abap_char_utilities=>newline in l_value with '\n' .
1102           replace all occurrences of cl_abap_char_utilities=>horizontal_tab in l_value with '\t' .
1103           replace all occurrences of cl_abap_char_utilities=>backspace in l_value with '\b' .
1104           replace all occurrences of cl_abap_char_utilities=>form_feed in l_value with '\f' .
1105 
1106         when 'y'.  " XSTRING
1107 * Put the XSTRING in Base64
1108 *          l_value = cl_http_utility=>ENCODE_X_BASE64(  ).
1109           l_value = 'XSTRING not supported in YAML yet!'.
1110 
1111         when others.
1112 * Don't hesitate to add and modify abap types to suit your taste.
1113 
1114       endcase.
1115 
1116 * We use YAML scalars double quoted
1117       if dont_quote ne 'X'.
1118         concatenate c_quote l_value c_quote into l_value.
1119       else.
1120         clear dont_quote.
1121       endif.
1122 
1123       append l_value to yaml_fragments.
1124 
1125       append xnl to yaml_fragments.
1126 
1127     endif. " is structure or scalar
1128 
1129   endif. " main typekind sentence
1130 
1131 
1132 
1133 * Use a loop in older releases that don't support concatenate lines.
1134   concatenate lines of yaml_fragments into yaml_string respecting blanks.
1135 
1136 endmethod.
1137 
1138 
1139 * ---------------------------------------------------------------------------------------+
1140 * | Static Public Method ZCL_JSON_HANDLER=>BUILD_PARAMS
1141 * +-------------------------------------------------------------------------------------------------+
1142 * | [--->] FUNCTION_NAME                  TYPE        RS38L_FNAM
1143 * | [<---] PARAMTAB                       TYPE        ABAP_FUNC_PARMBIND_TAB
1144 * | [<---] EXCEPTAB                       TYPE        ABAP_FUNC_EXCPBIND_TAB
1145 * | [<---] PARAMS                         TYPE        ANY
1146 * | [EXC!] INVALID_FUNCTION
1147 * | [EXC!] UNSUPPORTED_PARAM_TYPE
1148 * +--------------------------------------------------------------------------------------
1149 method BUILD_PARAMS.
1150 
1151   type-pools: ABAP.
1152 
1153   data defval type RS38L_DEFO.
1154   data dataname type string.
1155   data waref type ref to data.
1156 
1157   field-symbols:
1158      type any,
1159      type any.
1160 
1161   data len type i.
1162   data excnt type i value 1.
1163 
1164   data paramline  type line  of ABAP_FUNC_PARMBIND_TAB.
1165   data exceptline type line  of ABAP_FUNC_EXCPBIND_TAB.
1166   data t_params_p type table of RFC_FINT_P.
1167   data params_p   type RFC_FINT_P.
1168 
1169   define remove_enclosing_quotes.
1170     " Remove enclosing single quotes
1171     if &2 gt 1.
1172       subtract 1 from &2.
1173       if &1+&2 eq ''''.
1174         &1+&2 = space.
1175       endif.
1176       if &1(1) eq ''''.
1177         shift &1 left.
1178       endif.
1179       &2 = strlen( &1 ).
1180     endif.
1181   end-of-definition.
1182 
1183 
1184 * do we have the rfc name?
1185   call function 'RFC_GET_FUNCTION_INTERFACE_P'
1186     EXPORTING
1187       funcname      = function_name
1188       language      = 'E'       "'D'  "sy-langu
1189     TABLES
1190       params_p      = t_params_p
1191     EXCEPTIONS
1192       fu_not_found  = 1
1193       nametab_fault = 2
1194       others        = 3.
1195 
1196   if sy-subrc <> 0.
1197     raise INVALID_FUNCTION.
1198   endif.
1199 
1200 
1201 * Build params table
1202   loop at t_params_p into params_p.
1203 
1204     unassign .
1205     unassign .
1206     clear paramline.
1207 
1208     case params_p-paramclass.
1209 
1210       when 'I' or 'E' or 'C'.
1211 
1212         paramline-name = params_p-parameter.
1213 
1214         if params_p-paramclass = 'E'.
1215           paramline-kind = ABAP_FUNC_IMPORTING.
1216         elseif params_p-paramclass = 'I'.
1217           paramline-kind = ABAP_FUNC_EXPORTING.
1218         else.
1219           paramline-kind = ABAP_FUNC_CHANGING.
1220         endif.
1221 
1222         if params_p-fieldname is initial.
1223           dataname = params_p-tabname.
1224         else.
1225           concatenate params_p-tabname params_p-fieldname into
1226               dataname separated by '-'.
1227         endif.
1228 
1229 * Assign default values
1230         defval = params_p-default.
1231         if dataname is initial.
1232            dataname = 'STRING'.  " use a STRING for this cases (see CONVERT_DATE_TO_EXTERNAL).
1233         endif.
1234         create data waref type (dataname).
1235         assign waref->* to .
1236         len = strlen( defval ).
1237         remove_enclosing_quotes defval len.
1238         if defval = 'SPACE'.
1239            = space.
1240         elseif len > 3 and defval+0(3) = 'SY-'.
1241           assign (defval) to .
1242            = .
1243           unassign .
1244         else.
1245           if defval is not initial.
1246              = defval.
1247           endif.
1248         endif.
1249         unassign .
1250         paramline-value = waref.
1251         insert paramline into table paramtab.
1252 
1253       when 'T'.
1254         paramline-name = params_p-parameter.
1255         paramline-kind = ABAP_FUNC_TABLES.
1256         if params_p-exid eq 'h'.
1257           create data waref type (params_p-tabname).
1258         else.
1259           create data waref type standard table of (params_p-tabname).
1260         endif.
1261         paramline-value = waref.
1262         insert paramline into table paramtab.
1263 
1264       when 'X'.
1265         exceptline-name = params_p-parameter.
1266         exceptline-value = excnt.
1267         data messg type ref to data.
1268         create data messg type string.
1269         assign messg->* to .
1270          = params_p-paramtext.
1271         exceptline-message = messg.
1272         insert exceptline into table exceptab.
1273         add 1 to excnt.
1274 
1275       when others.
1276         raise UNSUPPORTED_PARAM_TYPE.
1277 
1278     endcase.
1279 
1280   endloop.
1281 
1282 
1283 * add in the catch all exception
1284   exceptline-name = 'OTHERS'.
1285   exceptline-value = excnt.
1286   insert exceptline into table exceptab.
1287 
1288 
1289 * return
1290   params = t_params_p.
1291 
1292 *********************************
1293 ******* Remaining from 2006 *****
1294 ******* end of build_params *****
1295 *********************************
1296 endmethod.
1297 
1298 
1299 * ---------------------------------------------------------------------------------------+
1300 * | Static Public Method ZCL_JSON_HANDLER=>DESERIALIZE_ID
1301 * +-------------------------------------------------------------------------------------------------+
1302 * | [--->] JSON                           TYPE        STRING
1303 * | [<-->] PARAMTAB                       TYPE        ABAP_FUNC_PARMBIND_TAB
1304 * | [!CX!] ZCX_JSON
1305 * +--------------------------------------------------------------------------------------
1306 method DESERIALIZE_ID.
1307 */***********************************************************/*
1308 */ New method using the built-in transformation              /*
1309 */ included in releases 7.02 and 7.03/7.31 (Kernelpatch 116) /*
1310 */***********************************************************/*
1311 
1312   type-pools: ABAP.
1313 
1314 ** Remember function parameter types
1315 **constants:
1316 **  abap_func_exporting type abap_func_parmbind-kind value 10,
1317 **  abap_func_importing type abap_func_parmbind-kind value 20,
1318 **  abap_func_tables    type abap_func_parmbind-kind value 30,
1319 **  abap_func_changing  type abap_func_parmbind-kind value 40.
1320 
1321   data:
1322     rtab       type ABAP_TRANS_RESBIND_TAB,
1323     rlin       type abap_trans_resbind,
1324     oexcp      type ref to cx_root,
1325     etext      type string,
1326     json_xtext type xstring.
1327 
1328   field-symbols  type abap_func_parmbind.
1329 
1330   if json is initial. exit. endif.  " exit method if there is nothing to parse
1331 
1332   " build rtab table for transformation id
1333 
1334   loop at paramtab assigning .
1335     if -kind eq abap_func_importing. "" va al revés, cuidado!!!
1336       continue.
1337     endif.
1338     rlin-name  = -name.
1339     rlin-value = -value.
1340     append rlin to rtab.
1341   endloop.
1342 
1343   " Convert input JSON variable names to uppercase
1344 
1345   json_xtext = cl_abap_codepage=>convert_to( json ).
1346   data(reader) = cl_sxml_string_reader=>create( json_xtext ).
1347   data(writer) = cast if_sxml_writer( cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ) ).
1348   do.
1349     data(node) = reader->read_next_node( ).
1350     if node is initial.
1351       exit.
1352     endif.
1353     if node->type = if_sxml_node=>co_nt_element_open.
1354       data(attributes)  = cast if_sxml_open_element( node )->get_attributes( ).
1355       loop at attributes assigning field-symbol().
1356         if ->qname-name = 'name'.
1357           ->set_value(
1358             to_upper( ->get_value( ) ) ).
1359         endif.
1360       endloop.
1361     endif.
1362     writer->write_node( node ).
1363   enddo.
1364   json_xtext = cast cl_sxml_string_writer( writer )->get_output( ) .
1365 
1366   try.
1367 
1368       CALL TRANSFORMATION id SOURCE XML json_xtext
1369                              RESULT (rtab).
1370 
1371     catch cx_root into oexcp.
1372 
1373       etext = oexcp->if_message~get_text( ).
1374       RAISE EXCEPTION type zcx_json
1375         EXPORTING
1376           message = etext.
1377 
1378   endtry.
1379 
1380 endmethod.
1381 
1382 
1383 * ---------------------------------------------------------------------------------------+
1384 * | Instance Public Method ZCL_JSON_HANDLER->IF_HTTP_EXTENSION~HANDLE_REQUEST
1385 * +-------------------------------------------------------------------------------------------------+
1386 * | [--->] SERVER                         TYPE REF TO IF_HTTP_SERVER
1387 * +--------------------------------------------------------------------------------------
1388 METHOD if_http_extension~handle_request.
1389 */*************************************************************************/
1390 */ Assign this handler to a service in ICF. This allows any ABAP function */
1391 */ module to be called directly by URL and exchange data in JSON format.  */
1392 */ --
1393 */ This code is distributed under the terms of Apache License Version 2.0 */
1394 */ (see http://www.apache.org/licenses/LICENSE-2.0.html)                  */
1395 */ --
1396 */ (C) César Martín                                 */
1397 */ Many thanks to Juan Díez for his ideas, help, and support.             */
1398 */ --
1399 */*************************************************************************/
1400 */ If you want to use the SAP standard provided transformation for JSON   */
1401 */ and XML, uncomment the lines calling serialize_id and deserialize_id   */
1402 */*************************************************************************/
1403   "INCLUDE zafl_macros."陈辉 增加日志
1404   TYPE-POOLS abap.
1405 
1406   DATA: show_import_params TYPE abap_bool VALUE abap_false,
1407         upcase             TYPE abap_bool VALUE abap_false,
1408         lowercase          TYPE abap_bool VALUE abap_true,
1409         camelcase          TYPE abap_bool VALUE abap_false,
1410         path_info          TYPE string,
1411         p_info_tab         TYPE TABLE OF string,
1412         format             TYPE string,
1413         accept             TYPE string,
1414         action             TYPE string,
1415         request_method     TYPE string,
1416         jsonp_callback     TYPE string,
1417         i_content_type     TYPE string,
1418         i_cdata            TYPE string,
1419         o_cdata            TYPE string,
1420         exceptheader       TYPE string,
1421         etext              TYPE string,
1422         etext2             TYPE string,
1423         str_item           TYPE string,
1424         host               TYPE string,
1425         port               TYPE string,
1426         proto              TYPE string,
1427         http_code          TYPE i,
1428         http_status        TYPE string,
1429         camelcase_names    TYPE stringtab,
1430 
1431         funcname           TYPE rs38l_fnam,
1432         funcname2          TYPE string,
1433         dparam             TYPE abap_parmname,
1434         t_params_p         TYPE STANDARD TABLE OF rfc_fint_p,
1435         paramtab           TYPE abap_func_parmbind_tab,
1436         exceptab           TYPE abap_func_excpbind_tab,
1437         exception          TYPE LINE OF abap_func_excpbind_tab,
1438         funcrc             TYPE sy-subrc,
1439         oexcp              TYPE REF TO cx_root,
1440         qs_nvp             TYPE tihttpnvp,
1441         l_lines            TYPE i,
1442         l_idx              TYPE i.
1443 
1444   TYPES:BEGIN OF ty_icf,
1445           request_method  TYPE string,
1446           http_code       TYPE i,
1447           http_status     TYPE string,
1448           error_message   TYPE string,
1449           location_header TYPE string,
1450           icf_url         TYPE string,
1451           icf_service     TYPE string,
1452           path_info       TYPE string,
1453           delete_params   TYPE stringtab,
1454           i_json_data     TYPE string,
1455           qs_tab          TYPE tihttpnvp,
1456           alt_response    TYPE string,
1457           server          TYPE REF TO if_http_server,
1458           camelcase_names TYPE stringtab,
1459         END OF ty_icf.
1460   FIELD-SYMBOLS  TYPE ihttpnvp.
1461   FIELD-SYMBOLS  TYPE abap_func_parmbind.
1462   FIELD-SYMBOLS  TYPE string.
1463   FIELD-SYMBOLS  TYPE i.
1464   FIELD-SYMBOLS  TYPE ty_icf. "zicf_handler_data.
1465 
1466   DEFINE http_error.
1467     "   &1   http status code
1468     "   &2   status text
1469     "   &3   error message
1470     server->response->set_header_field( name = 'Content-Type'  value = 'application/json' ).
1471     http_code = &1.
1472     server->response->set_status( code = http_code  reason = &2 ).
1473     CONCATENATE '{"ERROR_CODE":"' &1 '","ERROR_MESSAGE":"' &3 '","INFO_LINK":"' me->my_url me->my_service '?action=notes"}' INTO etext.
1474     server->response->set_cdata( etext ).
1475     EXIT.
1476   END-OF-DEFINITION.
1477 
1478 * Get Server Info:
1479 
1480   server->get_location( IMPORTING host = host  port = port  out_protocol = proto ).
1481   CONCATENATE proto '://' host ':' port INTO me->my_url.
1482 
1483 ** Get all client Info:
1484 *data clnt_hfields type TIHTTPNVP.
1485 *server->request->get_header_fields( changing fields = clnt_hfields ).
1486 
1487 
1488 * GET and POST and other methods are allowed.
1489 * Uncomment or extend this if you want alternative actions following
1490 * request methods, in order to define a REST style behaviour
1491 * or, better, check an alternative approach on a way to do that
1492 * inside the FM (search for _ICF_DATA below).
1493 *  if request_method <> 'POST'.
1494 ****    http_error 405 'Method not allowed' 'Method not allowed.'.
1495 *  endif.
1496 
1497 
1498 * Get form and header fields
1499   me->my_service         = server->request->get_header_field( name = '~script_name' ).
1500   request_method         = server->request->get_header_field( name = '~request_method' ).
1501   i_content_type         = server->request->get_header_field( name = 'content-type' ).
1502   show_import_params   = server->request->get_form_field( 'show_import_params' ).
1503   action                 = server->request->get_form_field( 'action' ).
1504   jsonp_callback         = server->request->get_form_field( 'callback' ).
1505   format               = server->request->get_form_field( 'format' ).
1506   accept               = server->request->get_header_field( name = 'Accept' ).
1507 
1508 * the case with CASE and forgive the mess.
1509 * Now, it is lowercase by default.
1510   lowercase              = server->request->get_form_field( 'lowercase' ).
1511   upcase              = server->request->get_form_field( 'upcase' ).
1512   camelcase              = server->request->get_form_field( 'camelcase' ).
1513   IF upcase NE abap_true. " only upcase matters.
1514     lowercase = abap_true.
1515   ENDIF.
1516 
1517 
1518 * Try "$" equivalents:
1519   IF format IS INITIAL.
1520     format = server->request->get_form_field( '$format' ).
1521   ENDIF.
1522   IF jsonp_callback IS INITIAL.
1523     jsonp_callback = server->request->get_form_field( '$callback' ).
1524   ENDIF.
1525 
1526 * Get function name from PATH_INFO
1527   path_info = server->request->get_header_field( name = '~path_info' ).
1528   SPLIT path_info AT '/' INTO TABLE p_info_tab.
1529   READ TABLE p_info_tab INDEX 2 INTO funcname.
1530   READ TABLE p_info_tab INDEX 3 INTO funcname2.
1531   IF sy-subrc EQ 0.
1532     CONCATENATE '/' funcname '/' funcname2 INTO funcname.
1533     CONDENSE funcname.
1534   ENDIF.
1535   TRANSLATE funcname TO UPPER CASE.
1536   IF funcname IS INITIAL AND action IS INITIAL.
1537     http_error '404' 'Not Found' 'Empty request.' .
1538   ENDIF.
1539 
1540 * Get the desired response format from "Accept" header (as in RFC 2616 sec 14.1)
1541 * See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html. Thanks Uwe!!
1542   IF accept IS NOT INITIAL AND format IS INITIAL.
1543     TRANSLATE accept TO LOWER CASE.
1544     IF accept CS '/json'.
1545       format = 'json'.
1546     ELSEIF accept CS '/yaml'.
1547       format = 'yaml'.
1548     ELSEIF accept CS '/xml'.
1549       format = 'xml'.
1550     ELSEIF accept CS '/perl'.
1551       format = 'perl'.
1552     ELSEIF accept CS '*/*'.
1553       CLEAR format.  " for the moment, ignore quality levels in Accept, send default format (json).
1554     ELSE.
1555       http_error '406' 'Not Acceptable' 'The server cannot send a response which is acceptable according to the combined Accept field value'.
1556     ENDIF.
1557   ENDIF.
1558 
1559   TRANSLATE format TO UPPER CASE.
1560   TRANSLATE action TO UPPER CASE.
1561   IF show_import_params IS NOT INITIAL.
1562     show_import_params = abap_true.
1563   ENDIF.
1564 
1565 
1566 ***************************
1567 * Do alternative actions...
1568   CASE action.
1569     WHEN 'NOTES'.
1570       server->response->set_header_field( name = 'Content-Type'  value = 'text/html' ).
1571       server->response->set_status( code = 200 reason = 'OK' ).
1572       o_cdata = me->notes( ).
1573       server->response->set_cdata( o_cdata ).
1574       EXIT.
1575 *    when 'TEST'.
1576 ****** TEST *****
1577 *      etext = me->test( i_cdata ).
1578 *      http_error '200' 'Ok' etext.
1579 *      exit.
1580 ****** Investigate further... *****
1581     WHEN 'START_SESSION'.
1582 **      server->stateful = 1.
1583       server->set_session_stateful( stateful = server->co_enabled ).
1584     WHEN 'END_SESSION'.
1585 **      server->stateful = 0.
1586       server->set_session_stateful( stateful = server->co_disabled ).
1587     WHEN OTHERS.
1588       " just go on
1589   ENDCASE.
1590 
1591 
1592 
1593 * Check Authorization. Create the relevant auth object in SU21 and assign
1594 * the authorized functions to the user. Uncomment to implement security.
1595 *  authority-check object 'Z_JSON'
1596 *         id 'FMNAME' field funcname.
1597 *  if sy-subrc ne 0.
1598 *    http_error '403' 'Not authorized' 'You are not authorized to invoke this function module.'.
1599 *  endif.
1600 
1601 *****************************************************************************
1602 * check CORS
1603 * see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS *
1604 *****************************************************************************
1605 
1606 
1607 
1608 ******************
1609 * get input data *
1610 ******************
1611   CLEAR i_cdata.
1612   i_cdata = server->request->get_cdata( ).
1613   server->request->get_form_fields_cs( CHANGING fields = qs_nvp ).
1614 
1615 * We map the query string to a simple JSON input. Handy for REST style queries.
1616 * The query string may come from GET requests in the url and content data in
1617 * POST request in x-www-form-urlencoded. ICF handles this perfectly and mixes both!! Great!!
1618   IF ( qs_nvp IS NOT INITIAL AND i_cdata IS INITIAL ) OR
1619       i_content_type CS 'application/x-www-form-urlencoded'.
1620     l_lines = lines( qs_nvp ).
1621     CLEAR l_idx.
1622     MOVE '{' TO i_cdata.
1623     LOOP AT qs_nvp ASSIGNING .
1624       ADD 1 TO l_idx.
1625       TRANSLATE -name TO UPPER CASE. " ABAP is upper case internally anyway.
1626       CONCATENATE i_cdata '"' -name '":"' -value '"' INTO i_cdata
1627         RESPECTING BLANKS.
1628       IF l_idx < l_lines.
1629         CONCATENATE i_cdata ',' INTO i_cdata RESPECTING BLANKS.
1630       ENDIF.
1631     ENDLOOP.
1632     CONCATENATE i_cdata '}' INTO i_cdata.
1633   ENDIF.
1634 
1635 
1636 
1637 * Prepare params to call function
1638   CALL METHOD zcl_json_handler=>build_params
1639     EXPORTING
1640       function_name    = funcname
1641     IMPORTING
1642       params           = t_params_p
1643       paramtab         = paramtab
1644       exceptab         = exceptab
1645     EXCEPTIONS
1646       invalid_function = 1
1647       OTHERS           = 2.
1648 
1649   IF sy-subrc <> 0.
1650     CONCATENATE 'Invalid Function. ' sy-msgid sy-msgty sy-msgno ': '
1651             sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
1652             INTO etext SEPARATED BY '-'.
1653     http_error '500' 'Server Error' etext.
1654   ENDIF.
1655 
1656 
1657 **********************
1658 * Process input data *
1659 **********************
1660   TRY.
1661       CALL METHOD me->json_deserialize     " The classic method using JavaScript (JSON only)
1662 *      CALL METHOD me->deserialize_id  " The new method using transformation id. This method accepts both JSON and XML input!!! Great!!
1663         EXPORTING
1664           json     = i_cdata
1665         CHANGING
1666           paramtab = paramtab.
1667 
1668     CATCH cx_root INTO oexcp.
1669 
1670       etext = oexcp->if_message~get_text( ).
1671 
1672       http_error '500' 'Internal Server Error' etext.
1673 
1674   ENDTRY.
1675 */**********************************/*
1676 */**********************************/*
1677 
1678 
1679 
1680 */************************************************/*
1681 */ Pass some request info to function module      /*
1682 */ for FMs implementing a REST model or whatever  /*
1683 */************************************************/*
1684   READ TABLE paramtab WITH KEY name = '_ICF_DATA' ASSIGNING .
1685   IF sy-subrc EQ 0.
1686     CREATE DATA -value TYPE zicf_handler_data.
1687     ASSIGN -value->* TO .
1688     -request_method = request_method.
1689     -icf_url = me->my_url.
1690     -icf_service = me->my_service.
1691     -path_info = path_info.
1692     -qs_tab = qs_nvp.
1693     -i_json_data = i_cdata.
1694     -camelcase_names = camelcase_names.
1695     APPEND '_ICF_DATA' TO -delete_params.
1696     -server = server. " Beware!
1697   ENDIF.
1698 
1699 
1700 
1701 ****************************
1702 * Call the function module *
1703 ****************************
1704   TRY.
1705       "/afl/log_init.
1706       CALL FUNCTION funcname
1707         PARAMETER-TABLE
1708         paramtab
1709         EXCEPTION-TABLE
1710         exceptab.
1711       "/afl/save.
1712     CATCH cx_root INTO oexcp.
1713 
1714       etext = oexcp->if_message~get_longtext(  preserve_newlines = abap_true ).
1715 
1716       http_error '500' 'Internal Server Error' etext.
1717 
1718   ENDTRY.
1719 
1720 
1721 * Remove unused exceptions
1722   funcrc = sy-subrc.
1723   DELETE exceptab WHERE value NE funcrc.
1724   READ TABLE exceptab INTO exception WITH KEY value = funcrc.
1725   IF sy-subrc EQ 0.
1726     exceptheader = exception-name.
1727     CALL METHOD server->response->set_header_field(
1728         name  = 'X-SAPRFC-Exception'
1729         value = exceptheader ).
1730   ENDIF.
1731 
1732 
1733 */*******************************************************************/*
1734 */ Read specific FM parameters for REST type interfaces              /*
1735 */ I need to find a way on how to operate with some http codes:       /*
1736 */ 201 Created - URI of resource created is set in Location header   /*
1737 */ 202 Accepted - Response contains status information
1738 */ 203 Non-Authoritative Information
1739 */ 204 No Content - NO CONTENT is sent, nothing, nada
1740 */ 205 Reset Content - NO CONTENT is sent, nothing, nada
1741 */ 206 Partial Content - probably will not implement this
1742 */ Codes 3xx, 4xx should also be handled.
1743 */***********************************/*
1744   IF  IS ASSIGNED.
1745     IF -http_code IS NOT INITIAL.
1746       server->response->set_status( code = -http_code  reason = -http_status ).
1747       CASE -http_code.
1748         WHEN 204 OR 205.
1749           EXIT.
1750         WHEN OTHERS. " many to add?
1751       ENDCASE.
1752     ENDIF.
1753     IF -error_message IS NOT INITIAL.
1754       str_item = -http_code. CONDENSE str_item.
1755       http_error str_item -http_status -error_message.
1756     ENDIF.
1757 * read camelcase_names
1758     camelcase_names = -camelcase_names.
1759 * Delete indicated params for not showing them in the response
1760     LOOP AT -delete_params INTO dparam.
1761       DELETE paramtab WHERE name EQ dparam.
1762     ENDLOOP.
1763   ENDIF.
1764 
1765 
1766 * Prepare response. Serialize to output format stream.
1767   CASE format.
1768 
1769     WHEN 'YAML'.
1770 
1771       CALL METHOD me->serialize_yaml
1772         EXPORTING
1773           paramtab    = paramtab
1774           exceptab    = exceptab
1775           params      = t_params_p
1776           jsonp       = jsonp_callback
1777           show_impp   = show_import_params
1778           lowercase   = lowercase
1779         IMPORTING
1780           yaml_string = o_cdata.
1781 
1782       server->response->set_header_field( name = 'Content-Type' value = 'text/plain' ).
1783 
1784     WHEN 'PERL'.
1785 
1786       CALL METHOD me->serialize_perl
1787         EXPORTING
1788           paramtab    = paramtab
1789           exceptab    = exceptab
1790           params      = t_params_p
1791           jsonp       = jsonp_callback
1792           show_impp   = show_import_params
1793           funcname    = funcname
1794           lowercase   = lowercase
1795         IMPORTING
1796           perl_string = o_cdata.
1797 
1798       server->response->set_header_field( name = 'Content-Type' value = 'text/plain' ).
1799 
1800     WHEN 'XML'.
1801 
1802       CALL METHOD me->serialize_xml
1803 *      CALL METHOD me->serialize_id
1804         EXPORTING
1805           paramtab  = paramtab
1806           exceptab  = exceptab
1807           params    = t_params_p
1808           jsonp     = jsonp_callback
1809           show_impp = show_import_params
1810           funcname  = funcname
1811           lowercase = lowercase
1812           format    = format
1813         IMPORTING
1814           o_string  = o_cdata.
1815 
1816       server->response->set_header_field( name = 'Content-Type' value = 'application/xml' ).
1817 
1818     WHEN OTHERS. " the others default to JSON.
1819 
1820       format = 'JSON'.
1821       CALL METHOD me->serialize_json
1822 *      CALL METHOD me->serialize_id
1823         EXPORTING
1824           paramtab        = paramtab
1825           exceptab        = exceptab
1826           params          = t_params_p
1827           jsonp           = jsonp_callback
1828           show_impp       = show_import_params
1829           lowercase       = lowercase
1830           camelcase       = camelcase
1831           camelcase_names = camelcase_names
1832 *         format          = format
1833         IMPORTING
1834           o_string        = o_cdata.
1835 
1836       server->response->set_header_field( name = 'Content-Type' value = 'application/json' ).
1837       IF jsonp_callback IS NOT INITIAL.
1838         server->response->set_header_field( name = 'Content-Type' value = 'application/javascript' ).
1839       ENDIF.
1840 
1841   ENDCASE.
1842 
1843 
1844 * Set response:
1845   server->response->set_header_field( name = 'X-Data-Format' value = format ). "
1846 * Activate compression (will compress when size>1kb if requested by client in Accept-Encoding: gzip. Very nice.).
1847   server->response->set_compression( ).
1848 *  if -alt_response is not initial.
1849 *    o_cdata = -alt_response.
1850 *  endif.
1851   server->response->set_cdata( data = o_cdata ).
1852 
1853 *******************************************
1854 *******************************************
1855 **********      *      *          *********
1856 *********        *      *        **********
1857 ********          *      *      ***********
1858 *******************************************
1859 *******************************************
1860 ENDMETHOD.
1861 
1862 
1863 * ---------------------------------------------------------------------------------------+
1864 * | Static Public Method ZCL_JSON_HANDLER=>JSON2ABAP
1865 * +-------------------------------------------------------------------------------------------------+
1866 * | [--->] JSON_STRING                    TYPE        STRING(optional)
1867 * | [--->] VAR_NAME                       TYPE        STRING(optional)
1868 * | [--->] PROPERTY_PATH                  TYPE        STRING (default ='json_obj')
1869 * | [<---] PROPERTY_TABLE                 TYPE        JS_PROPERTY_TAB
1870 * | [<-->] JS_OBJECT                      TYPE REF TO CL_JAVA_SCRIPT(optional)
1871 * | [<-->] ABAP_DATA                      TYPE        ANY(optional)
1872 * | [!CX!] ZCX_JSON
1873 * +--------------------------------------------------------------------------------------
1874 method JSON2ABAP.
1875 */************************************************/*
1876 */ Input any abap data and this method tries to   /*
1877 */ fill it with the data in the JSON string.      /*
1878 */  Thanks to Juan Diaz for helping here!!        /*
1879 */************************************************/*
1880 
1881   type-pools: abap, js.
1882 
1883   data:
1884     js_script         type string,
1885     js_started        type i value 0,
1886     l_json_string     type string,
1887     js_property_table type   js_property_tab,
1888     js_property       type line of js_property_tab,
1889     l_property_path   type string,
1890     compname          type string,
1891     item_path         type string.
1892 
1893   data:
1894     l_type   type c,
1895     l_value  type string,
1896     linetype type string,
1897     l_comp   type line of ABAP_COMPDESCR_TAB.
1898 
1899   data:
1900     datadesc type ref to CL_ABAP_TYPEDESCR,
1901     drefdesc type ref to CL_ABAP_TYPEDESCR,
1902     linedesc type ref to CL_ABAP_TYPEDESCR,
1903     strudesc type ref to CL_ABAP_STRUCTDESCR,
1904     tabldesc type ref to CL_ABAP_TABLEDESCR.
1905 
1906   data newline type ref to data.
1907 
1908   field-symbols:
1909      type any,
1910           type any table,
1911           type any,
1912         type line of js_property_tab,
1913       type abap_compdescr.
1914 
1915 
1916   define assign_scalar_value.
1917     "   &1   
1918     "   &2   js_property-value
1919     describe field &1 type l_type.
1920     l_value = &2.
1921 * convert or adapt scalar values to ABAP.
1922     case l_type.
1923       when 'D'. " date type
1924         if l_value cs '-'.
1925           replace all occurrences of '-' in l_value with space.
1926           condense l_value no-gaps.
1927         endif.
1928       when 'T'. " time type
1929         if l_value cs ':'.
1930           replace all occurrences of ':' in l_value with space.
1931           condense l_value no-gaps.
1932         endif.
1933       when others.
1934         " may be other conversions or checks could be implemented here.
1935     endcase.
1936     &1 = l_value.
1937   end-of-definition.
1938 
1939 
1940   if js_object is not bound.
1941 
1942     if json_string is initial. exit. endif. " exit method if there is nothing to parse
1943 
1944     l_json_string = json_string.
1945     " js_object = cl_java_script=>create( STACKSIZE = 16384 ).
1946     js_object = cl_java_script=>create( STACKSIZE = 16384 HEAPSIZE = 960000 ).
1947 
1948 ***************************************************
1949 *  Parse JSON using JavaScript                    *
1950 ***************************************************
1951     js_object->bind( exporting name_obj = 'abap_data' name_prop = 'json_string'    changing data = l_json_string ).
1952     js_object->bind( exporting name_obj = 'abap_data' name_prop = 'script_started' changing data = js_started ).
1953 
1954 * We use the JavaScript engine included in ABAP to read the JSON string.
1955 * We simply use the recommended way to eval a JSON string as specified
1956 * in RFC 4627 (http://www.ietf.org/rfc/rfc4627.txt).
1957 *
1958 * Security considerations:
1959 *
1960 *   Generally there are security issues with scripting languages.  JSON
1961 *   is a subset of JavaScript, but it is a safe subset that excludes
1962 *   assignment and invocation.
1963 *
1964 *   A JSON text can be safely passed into JavaScript's eval() function
1965 *   (which compiles and executes a string) if all the characters not
1966 *   enclosed in strings are in the set of characters that form JSON
1967 *   tokens.  This can be quickly determined in JavaScript with two
1968 *   regular expressions and calls to the test and replace methods.
1969 *
1970 *      var my_JSON_object = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
1971 *             text.replace(/"(\\.|[^"\\])*"/g, ''))) &&
1972 *         eval('(' + text + ')');
1973 
1974     concatenate
1975 
1976          'var json_obj; '
1977          'var json_text; '
1978 
1979          'function start() { '
1980          '  if(abap_data.script_started) { return; } '
1981          '  json_text = abap_data.json_string;'
1982          '  json_obj = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test( '
1983          '      json_text.replace(/"(\\.|[^"\\])*"/g, ''''))) && '
1984          '    eval(''('' + json_text + '')''); '
1985          '  abap_data.script_started = 1; '
1986          '} '
1987 
1988          'if(!abap_data.script_started) start(); '
1989 
1990 
1991        into js_script respecting blanks separated by xnl.
1992 
1993     js_object->compile( script_name = 'json_parser'     script = js_script ).
1994     js_object->execute( script_name = 'json_parser' ).
1995 
1996     if js_object->last_error_message is not initial.
1997       RAISE EXCEPTION type zcx_json
1998         EXPORTING
1999           message = js_object->last_error_message.
2000     endif.
2001 
2002   endif.
2003 ** End of JS processing.
2004 
2005 **
2006   if var_name is not initial.
2007     concatenate property_path var_name into l_property_path separated by '.'.
2008   else.
2009     l_property_path = property_path.
2010   endif.
2011 **
2012 **
2013   js_property_table = js_object->get_properties_scope_global( property_path = l_property_path ).
2014   property_table = js_property_table.
2015 
2016 * Exit if abap_data is not supplied, normally when called
2017 * from json_deserialize to get top level properties
2018   if abap_data is not supplied.
2019     exit.
2020   endif. "***
2021 
2022 *
2023 * Get ABAP data type, dereference if necessary and start
2024   datadesc = cl_abap_typedescr=>DESCRIBE_BY_DATA( abap_data ).
2025   if datadesc->kind eq cl_abap_typedescr=>kind_ref.
2026     assign abap_data->* to .
2027   else.
2028     assign abap_data to .
2029   endif.
2030   datadesc = cl_abap_typedescr=>DESCRIBE_BY_DATA(  ).
2031 
2032 
2033   case datadesc->kind.
2034 
2035     when cl_abap_typedescr=>kind_elem.
2036 * Scalar: process ABAP elements. Assume no type conversions for the moment.
2037       if var_name is initial.
2038         RAISE EXCEPTION type zcx_json
2039           EXPORTING
2040             message = 'VAR_NAME is required for scalar values.'.
2041       endif.
2042       js_property_table = js_object->get_properties_scope_global( property_path = property_path ).
2043       read table js_property_table with key name = var_name into js_property.
2044       if sy-subrc eq 0.
2045         assign_scalar_value  js_property-value.
2046       endif.
2047 
2048 
2049     when cl_abap_typedescr=>kind_struct.
2050 * Process ABAP structures
2051       strudesc ?= datadesc.
2052       loop at js_property_table assigning .
2053         compname = -name.
2054         translate compname to upper case.
2055         read table strudesc->COMPONENTS with key name = compname into l_comp.
2056         if sy-subrc eq 0.
2057           assign component l_comp-name of structure  to .
2058           case l_comp-type_kind.
2059             when    cl_abap_typedescr=>TYPEKIND_STRUCT1  " 'v'
2060                  or cl_abap_typedescr=>TYPEKIND_STRUCT2  " 'u'
2061                  or cl_abap_typedescr=>TYPEKIND_TABLE.   " 'h' (may need a different treatment one day)
2062               concatenate l_property_path -name into item_path separated by '.'.
2063 *> Recursive call here
2064               json2abap( exporting property_path = item_path changing abap_data =  js_object = js_object ).
2065 
2066             when others.
2067 * Process scalars in structures (same as the kind_elem above)
2068               assign_scalar_value  -value.
2069 
2070           endcase.
2071         endif.
2072       endloop.
2073 
2074     when cl_abap_typedescr=>kind_table.
2075 * Process ABAP tables
2076       if js_property_table is not initial.
2077         tabldesc ?= datadesc.
2078         linedesc = tabldesc->get_table_line_type( ).
2079         linetype = linedesc->get_relative_name( ).
2080         assign  to .
2081         loop at js_property_table into js_property where name NE 'length'. " the JS object length
2082           create data newline type (linetype).
2083           assign newline->* to .
2084           case js_property-kind.
2085             when 'O'.
2086               concatenate l_property_path js_property-name into item_path separated by '.'.
2087               condense item_path.
2088 *> Recursive call here
2089               json2abap( exporting property_path = item_path changing abap_data = newline js_object = js_object ).
2090             when others. " Assume scalars, 'S', 'I', or other JS types
2091               " Process scalars in plain table components(same as the kind_elem above)
2092               assign_scalar_value  js_property-value.
2093           endcase.
2094           insert  into table .
2095           free newline.
2096         endloop.
2097       endif.
2098 
2099     when others. " kind_class, kind_intf
2100       " forget it.
2101 
2102   endcase.
2103 
2104 
2105 endmethod.
2106 
2107 
2108 * ---------------------------------------------------------------------------------------+
2109 * | Static Public Method ZCL_JSON_HANDLER=>JSON_DESERIALIZE
2110 * +-------------------------------------------------------------------------------------------------+
2111 * | [--->] JSON                           TYPE        STRING
2112 * | [<-->] PARAMTAB                       TYPE        ABAP_FUNC_PARMBIND_TAB
2113 * | [!CX!] ZCX_JSON
2114 * +--------------------------------------------------------------------------------------
2115 method JSON_DESERIALIZE.
2116 
2117   type-pools: ABAP, JS.
2118 
2119 ** Remember function parameter types
2120 **constants:
2121 **  abap_func_exporting type abap_func_parmbind-kind value 10,
2122 **  abap_func_importing type abap_func_parmbind-kind value 20,
2123 **  abap_func_tables    type abap_func_parmbind-kind value 30,
2124 **  abap_func_changing  type abap_func_parmbind-kind value 40.
2125 
2126   data paramname   type string.
2127   data js_obj      type ref to cl_java_script.
2128   data js_prop_tab type js_property_tab.
2129 
2130   field-symbols  type line of js_property_tab.
2131   field-symbols     type abap_func_parmbind.
2132 
2133   if json is initial. exit. endif.
2134 
2135   json2abap( exporting json_string = json  importing property_table = js_prop_tab  changing js_object = js_obj ).
2136 
2137   loop at js_prop_tab assigning .
2138     paramname = -name.
2139     translate paramname to upper case.
2140     read table paramtab with key name = paramname assigning .
2141     if sy-subrc eq 0.
2142       if -kind ne abap_func_importing. "" va al revés, cuidado!!!
2143         json2abap( exporting var_name = -name  changing abap_data = -value js_object = js_obj ).
2144       endif.
2145     endif.
2146   endloop.
2147 
2148 endmethod.
2149 
2150 
2151 * ---------------------------------------------------------------------------------------+
2152 * | Instance Public Method ZCL_JSON_HANDLER->NOTES
2153 * +-------------------------------------------------------------------------------------------------+
2154 * | [<-()] TEXT                           TYPE        STRING
2155 * +--------------------------------------------------------------------------------------
2156 method NOTES.
2157 
2158 data location type string.
2159 
2160 concatenate me->my_url me->my_service '/RFC_SYSTEM_INFO' into location.
2161 
2162 concatenate
2163 
2164 'JSON (NEW) handler notes'
2165 
2166 '

About this service...

' 2167 'This is the ABAP implementation of a conversion program that' 2168 ' tranforms ABAP data into a JSON representation.' 2169 '

' 2170 'It provides a user interface in the form of a ICF service that ' 2171 'allows web invocation of ABAP function modules. It doesn''t matter if they are RFC enabled or not.' 2172 '

In this system this service has ' 2173 'been assigned to ICF service ' me->my_url me->my_service '">' me->my_service '.' 2174 '

' 2175 'In order to invoke a function module, just put its name in the PATH_INFO ' 2176 'of the service URL, as is shown in the following examples.' 2177 2178 '

Try the following link to do the default call in JSON format:

' location '?format=json">'
2179 location
2180 '?format=json
' 2181 2182 '

A simple syntax allows to get the output in different formats.

' 2183 2184 'The following gets the output in YAML format:' 2185 '

' location '?format=yaml">'
2186 location
2187 '?format=yaml
' 2188 '' 2189 '

And this will get the output in a basic XML representation:

' location '?format=xml">'
2190 location
2191 '?format=xml
' 2192 2193 '

And, just for fun, getting it into Perl format could be handy:

' location '?format=perl">'
2194 location
2195 '?format=perl
' 2196 2197 '

Finnally, you can add a callback to get the JSON response enclosed in a javascript function call,' 2198 ' in order to allow a JSONP style response: ' 2199 '

'
2200 location '?format=json&callback=callMe">'
2201 location '?format=json&callback=callMe
' 2202 2203 '

WARNING

This is work in progress and may not be suitable for use in productive
' 2204 'systems. The interface is somewhat unstable. Please feel free to test it and report ' 2205 'any bug and improvement you may find.' 2206 '

Use it at your own risk!' 2207 '

For more information: ' 2208 'https://cw.sdn.sap.com/cw/groups/json-adapter-for-abap-function-modules' 2209 '

' 2210 'If you have any questions, please contact me at ' 2211 'cesar.martin@sap.com' 2212 '

' 2213 2214 2215 '


' 2216 2217 2218 into text RESPECTING BLANKS. 2219 2220 2221 endmethod. 2222 2223 2224 * ---------------------------------------------------------------------------------------+ 2225 * | Static Public Method ZCL_JSON_HANDLER=>SERIALIZE_ID 2226 * +-------------------------------------------------------------------------------------------------+ 2227 * | [--->] PARAMTAB TYPE ABAP_FUNC_PARMBIND_TAB 2228 * | [--->] PARAMS TYPE ANY(optional) 2229 * | [--->] EXCEPTAB TYPE ABAP_FUNC_EXCPBIND_TAB(optional) 2230 * | [--->] SHOW_IMPP TYPE ABAP_BOOL(optional) 2231 * | [--->] JSONP TYPE STRING(optional) 2232 * | [--->] LOWERCASE TYPE ABAP_BOOL (default =ABAP_FALSE) 2233 * | [--->] FORMAT TYPE STRING (default ='JSON') 2234 * | [--->] FUNCNAME TYPE RS38L_FNAM(optional) 2235 * | [--->] CAMELCASE TYPE ABAP_BOOL (default =ABAP_FALSE) 2236 * | [<---] O_STRING TYPE STRING 2237 * | [!CX!] ZCX_JSON 2238 * +-------------------------------------------------------------------------------------- 2239 method SERIALIZE_ID. 2240 */***********************************************************/* 2241 */ New method using the built-in transformation /* 2242 */ included in releases 7.02 and 7.03/7.31 (Kernelpatch 116) /* 2243 */ Generates both JSON and XML formats!! 2244 */***********************************************************/* 2245 */ 2246 ** Remember function parameter types 2247 **constants: 2248 ** abap_func_exporting type abap_func_parmbind-kind value 10, 2249 ** abap_func_importing type abap_func_parmbind-kind value 20, 2250 ** abap_func_tables type abap_func_parmbind-kind value 30, 2251 ** abap_func_changing type abap_func_parmbind-kind value 40. 2252 2253 type-pools: ABAP. 2254 2255 data: 2256 stab type ABAP_TRANS_SRCBIND_TAB, 2257 slin type ABAP_TRANS_SRCBIND, 2258 oexcp type ref to cx_root, 2259 etext type string, 2260 adata type ref to data, 2261 json_writer type ref to cl_sxml_string_writer. 2262 2263 field-symbols type abap_func_parmbind. 2264 * field-symbols type abap_func_excpbind. 2265 2266 2267 loop at paramtab assigning . 2268 if show_impp ne 'X' 2269 and -kind eq abap_func_exporting. "" va al revés, cuidado!!! 2270 continue. 2271 endif. 2272 slin-name = -name. 2273 slin-value = -value. 2274 append slin to stab. clear slin. 2275 endloop. 2276 2277 if exceptab is not initial. 2278 slin-name = 'EXCEPTION'. 2279 get reference of exceptab into adata. 2280 slin-value = adata. 2281 append slin to stab. clear slin. 2282 endif. 2283 2284 2285 json_writer = cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ). 2286 2287 try. 2288 2289 case format. 2290 2291 when 'XML'. 2292 2293 call transformation id options data_refs = 'embedded' 2294 initial_components = 'include' 2295 source (stab) 2296 result xml o_string. 2297 2298 2299 when others. 2300 2301 call transformation id options data_refs = 'embedded' 2302 initial_components = 'include' 2303 source (stab) 2304 result xml json_writer. 2305 2306 o_string = cl_abap_codepage=>convert_from( json_writer->get_output( ) ). 2307 * json_string = json_writer->get_output( ). 2308 2309 if jsonp is not initial. 2310 concatenate jsonp '(' o_string ');' into o_string. 2311 endif. 2312 2313 endcase. 2314 2315 2316 catch cx_root into oexcp. 2317 2318 etext = oexcp->if_message~get_text( ). 2319 RAISE EXCEPTION type zcx_json 2320 EXPORTING 2321 message = etext. 2322 2323 endtry. 2324 2325 2326 endmethod. 2327 2328 2329 * ---------------------------------------------------------------------------------------+ 2330 * | Static Public Method ZCL_JSON_HANDLER=>SERIALIZE_JSON 2331 * +-------------------------------------------------------------------------------------------------+ 2332 * | [--->] PARAMTAB TYPE ABAP_FUNC_PARMBIND_TAB 2333 * | [--->] PARAMS TYPE ANY(optional) 2334 * | [--->] EXCEPTAB TYPE ABAP_FUNC_EXCPBIND_TAB(optional) 2335 * | [--->] SHOW_IMPP TYPE ABAP_BOOL(optional) 2336 * | [--->] JSONP TYPE STRING(optional) 2337 * | [--->] LOWERCASE TYPE ABAP_BOOL (default =ABAP_TRUE) 2338 * | [--->] CAMELCASE TYPE ABAP_BOOL (default =ABAP_FALSE) 2339 * | [--->] CAMELCASE_NAMES TYPE STRINGTAB(optional) 2340 * | [<---] O_STRING TYPE STRING 2341 * +-------------------------------------------------------------------------------------- 2342 method serialize_json. 2343 * ABAP based JSON serializer for function modules (January 2013). 2344 type-pools: abap. 2345 2346 ** Remember function parameter types 2347 **constants: 2348 ** abap_func_exporting type abap_func_parmbind-kind value 10, 2349 ** abap_func_importing type abap_func_parmbind-kind value 20, 2350 ** abap_func_tables type abap_func_parmbind-kind value 30, 2351 ** abap_func_changing type abap_func_parmbind-kind value 40. 2352 2353 data json_fragments type table of string. 2354 data rec_json_string type string. 2355 data paramname type string. 2356 data l_lines type i. 2357 data l_index type i. 2358 data upcase type xfeld value abap_true. 2359 data my_camelcase type xfeld. 2360 my_camelcase = camelcase. 2361 field-symbols type abap_func_parmbind. 2362 field-symbols type abap_func_excpbind. 2363 2364 if jsonp is not initial. 2365 append jsonp to json_fragments. 2366 append '(' to json_fragments. 2367 endif. 2368 2369 rec_json_string = '{'. 2370 append rec_json_string to json_fragments. 2371 clear rec_json_string. 2372 2373 clear l_index. 2374 l_lines = lines( paramtab ). 2375 2376 loop at paramtab assigning . 2377 if show_impp ne 'X' 2378 and -kind eq abap_func_exporting. "" va al revés, cuidado!!! 2379 subtract 1 from l_lines. 2380 continue. 2381 endif. 2382 add 1 to l_index. 2383 paramname = -name. 2384 if lowercase eq abap_true. 2385 translate paramname to lower case. 2386 " paramname = to_lower( paramname ). 2387 upcase = space. 2388 endif. 2389 if camelcase eq abap_true. 2390 paramname = to_mixed( val = paramname case = 'a'). 2391 else. 2392 read table camelcase_names from paramname transporting no fields. 2393 if sy-subrc eq 0. 2394 paramname = to_mixed( val = paramname case = 'a' ). 2395 my_camelcase = abap_true. 2396 else. 2397 my_camelcase = abap_false. 2398 endif. 2399 endif. 2400 rec_json_string = abap2json( abap_data = -value name = paramname upcase = upcase camelcase = my_camelcase camelcase_names = camelcase_names ). 2401 append rec_json_string to json_fragments. 2402 clear rec_json_string. 2403 if l_index < l_lines. 2404 append ',' to json_fragments . 2405 endif . 2406 endloop. 2407 2408 if exceptab is not initial. 2409 if l_lines gt 0. 2410 append ',' to json_fragments. 2411 endif. 2412 rec_json_string = abap2json( abap_data = exceptab upcase = 'X' name = 'EXCEPTION'). 2413 append rec_json_string to json_fragments. 2414 clear rec_json_string. 2415 endif. 2416 2417 rec_json_string = '}'. 2418 append rec_json_string to json_fragments. 2419 clear rec_json_string. 2420 2421 if jsonp is not initial. 2422 append ');' to json_fragments. 2423 endif. 2424 2425 concatenate lines of json_fragments into o_string. 2426 2427 endmethod. 2428 2429 2430 * ---------------------------------------------------------------------------------------+ 2431 * | Static Public Method ZCL_JSON_HANDLER=>SERIALIZE_PERL 2432 * +-------------------------------------------------------------------------------------------------+ 2433 * | [--->] PARAMTAB TYPE ABAP_FUNC_PARMBIND_TAB 2434 * | [--->] PARAMS TYPE ANY(optional) 2435 * | [--->] EXCEPTAB TYPE ABAP_FUNC_EXCPBIND_TAB(optional) 2436 * | [--->] SHOW_IMPP TYPE ABAP_BOOL(optional) 2437 * | [--->] JSONP TYPE STRING(optional) 2438 * | [--->] LOWERCASE TYPE ABAP_BOOL (default =ABAP_FALSE) 2439 * | [--->] FUNCNAME TYPE RS38L_FNAM 2440 * | [<---] PERL_STRING TYPE STRING 2441 * +-------------------------------------------------------------------------------------- 2442 method SERIALIZE_PERL. 2443 * Just for fun, generate data in Perl Data::Dumper format. 2444 2445 type-pools: ABAP. 2446 2447 **Remember function parameter types 2448 **constants: 2449 ** abap_func_exporting type abap_func_parmbind-kind value 10, 2450 ** abap_func_importing type abap_func_parmbind-kind value 20, 2451 ** abap_func_tables type abap_func_parmbind-kind value 30, 2452 ** abap_func_changing type abap_func_parmbind-kind value 40. 2453 2454 data perl_fragments type table of string. 2455 data rec_perl_string type string. 2456 data paramname type string. 2457 data l_lines type i. 2458 data l_index type i. 2459 data upcase type xfeld value 'X'. 2460 data perl_var type string. 2461 field-symbols type abap_func_parmbind. 2462 field-symbols type abap_func_excpbind. 2463 2464 if jsonp is not initial. 2465 perl_var = jsonp. 2466 else. 2467 perl_var = funcname. 2468 endif. 2469 concatenate '$' perl_var ' = {' into rec_perl_string. 2470 append rec_perl_string to perl_fragments. 2471 clear rec_perl_string. 2472 2473 clear l_index. 2474 l_lines = lines( paramtab ). 2475 2476 loop at paramtab assigning . 2477 if show_impp ne 'X' 2478 and -kind eq abap_func_exporting. "" va al revés, cuidado!!! 2479 subtract 1 from l_lines. 2480 continue. 2481 endif. 2482 add 1 to l_index. 2483 paramname = -name. 2484 if lowercase eq abap_true. 2485 translate paramname to lower case. 2486 upcase = space. 2487 endif. 2488 rec_perl_string = abap2perl( abap_data = -value name = paramname upcase = upcase ). 2489 append rec_perl_string to perl_fragments. 2490 clear rec_perl_string. 2491 if l_index < l_lines. 2492 append ',' to perl_fragments . 2493 endif . 2494 endloop. 2495 2496 if exceptab is not initial. 2497 if l_lines gt 0. 2498 append ',' to perl_fragments. 2499 endif. 2500 rec_perl_string = abap2perl( abap_data = exceptab upcase = 'X' name = 'EXCEPTION'). 2501 append rec_perl_string to perl_fragments. 2502 clear rec_perl_string. 2503 endif. 2504 2505 rec_perl_string = '};'. 2506 append rec_perl_string to perl_fragments. 2507 clear rec_perl_string. 2508 2509 concatenate lines of perl_fragments into perl_string. 2510 2511 endmethod. 2512 2513 2514 * ---------------------------------------------------------------------------------------+ 2515 * | Static Public Method ZCL_JSON_HANDLER=>SERIALIZE_XML 2516 * +-------------------------------------------------------------------------------------------------+ 2517 * | [--->] PARAMTAB TYPE ABAP_FUNC_PARMBIND_TAB 2518 * | [--->] PARAMS TYPE ANY(optional) 2519 * | [--->] EXCEPTAB TYPE ABAP_FUNC_EXCPBIND_TAB(optional) 2520 * | [--->] SHOW_IMPP TYPE ABAP_BOOL(optional) 2521 * | [--->] JSONP TYPE STRING(optional) 2522 * | [--->] FUNCNAME TYPE RS38L_FNAM 2523 * | [--->] LOWERCASE TYPE ABAP_BOOL (default =ABAP_FALSE) 2524 * | [--->] FORMAT TYPE STRING(optional) 2525 * | [<---] O_STRING TYPE STRING 2526 * +-------------------------------------------------------------------------------------- 2527 method SERIALIZE_XML. 2528 * Serialize function data into simple XML 2529 */ Look at method serialize_id for a new way of doing XML. 2530 2531 type-pools: ABAP. 2532 2533 ** Remember function parameter types 2534 ***constants: 2535 *** abap_func_exporting type abap_func_parmbind-kind value 10, 2536 *** abap_func_importing type abap_func_parmbind-kind value 20, 2537 *** abap_func_tables type abap_func_parmbind-kind value 30, 2538 *** abap_func_changing type abap_func_parmbind-kind value 40. 2539 2540 data rec_xml_string type string. 2541 data xml_fragments type table of string. 2542 data l_funcname type string. 2543 data paramname type string. 2544 field-symbols type abap_func_parmbind. 2545 field-symbols type abap_func_excpbind. 2546 data upcase type xfeld value 'X'. 2547 2548 constants: 2549 xml_head type string value '<?xml version="1.0" encoding="utf-8"?>'. 2550 2551 append xml_head to xml_fragments. 2552 2553 l_funcname = funcname. 2554 if lowercase eq abap_true. 2555 translate l_funcname to lower case. 2556 " just in case we call namespaced functions: 2557 replace all occurrences of '/' in l_funcname with '__'. 2558 upcase = space. 2559 endif. 2560 2561 concatenate '<' l_funcname '>' into rec_xml_string. 2562 append rec_xml_string to xml_fragments. 2563 2564 loop at paramtab assigning . 2565 if show_impp ne 'X' 2566 and -kind eq abap_func_exporting. "" va al revés, cuidado!!! 2567 continue. 2568 endif. 2569 paramname = -name. 2570 if lowercase eq abap_true. 2571 translate paramname to lower case. 2572 endif. 2573 rec_xml_string = abap2xml( name = paramname abap_data = -value upcase = upcase ). 2574 append rec_xml_string to xml_fragments. 2575 endloop. 2576 2577 if exceptab is not initial. 2578 rec_xml_string = abap2xml( name = 'EXCEPTION' abap_data = exceptab upcase = upcase ). 2579 append rec_xml_string to xml_fragments. 2580 endif. 2581 2582 concatenate '' l_funcname '>' into rec_xml_string. 2583 append rec_xml_string to xml_fragments. 2584 2585 concatenate lines of xml_fragments into o_string. 2586 2587 endmethod. 2588 2589 2590 * ---------------------------------------------------------------------------------------+ 2591 * | Static Public Method ZCL_JSON_HANDLER=>SERIALIZE_YAML 2592 * +-------------------------------------------------------------------------------------------------+ 2593 * | [--->] PARAMTAB TYPE ABAP_FUNC_PARMBIND_TAB 2594 * | [--->] PARAMS TYPE ANY(optional) 2595 * | [--->] EXCEPTAB TYPE ABAP_FUNC_EXCPBIND_TAB(optional) 2596 * | [--->] SHOW_IMPP TYPE ABAP_BOOL(optional) 2597 * | [--->] JSONP TYPE STRING(optional) 2598 * | [--->] LOWERCASE TYPE ABAP_BOOL (default =ABAP_FALSE) 2599 * | [<---] YAML_STRING TYPE STRING 2600 * +-------------------------------------------------------------------------------------- 2601 method SERIALIZE_YAML. 2602 * Now, go and represent function data in YAML (http://yaml.org) 2603 2604 type-pools: ABAP. 2605 ** Remember function parameter types 2606 **constants: 2607 ** abap_func_exporting type abap_func_parmbind-kind value 10, 2608 ** abap_func_importing type abap_func_parmbind-kind value 20, 2609 ** abap_func_tables type abap_func_parmbind-kind value 30, 2610 ** abap_func_changing type abap_func_parmbind-kind value 40. 2611 2612 data yaml_fragments type table of string. 2613 data rec_yaml_string type string. 2614 data rec_yaml_table type table of string. 2615 data paramname type string. 2616 field-symbols type abap_func_parmbind. 2617 field-symbols type abap_func_excpbind. 2618 data upcase type xfeld value 'X'. 2619 data yaml_head type string value '--- #YAML:1.0'. 2620 2621 concatenate yaml_head xnl into rec_yaml_string. 2622 append rec_yaml_string to yaml_fragments. 2623 clear rec_yaml_string. 2624 2625 loop at paramtab assigning . 2626 if show_impp ne 'X' 2627 and -kind eq abap_func_exporting. "" va al revés, cuidado!!! 2628 continue. 2629 endif. 2630 paramname = -name. 2631 if lowercase eq abap_true. 2632 translate paramname to lower case. 2633 upcase = space. 2634 endif. 2635 rec_yaml_string = abap2yaml( abap_data = -value name = paramname upcase = upcase ). 2636 append rec_yaml_string to yaml_fragments. 2637 clear rec_yaml_string. 2638 endloop. 2639 2640 if exceptab is not initial. 2641 rec_yaml_string = abap2yaml( abap_data = exceptab name = 'EXCEPTION' upcase = 'X' ). 2642 append rec_yaml_string to yaml_fragments. 2643 clear rec_yaml_string. 2644 endif. 2645 2646 * append xnl to yaml_fragments. 2647 2648 concatenate lines of yaml_fragments into yaml_string. 2649 2650 * if jsonp is not initial. 2651 * concatenate jsonp '(' yaml_string ');' into yaml_string. 2652 * endif. 2653 2654 endmethod. 2655 ENDCLASS.

SICF新建服务节点:

在 /sap/bc/节点下新建子节点ABAPAPI,在处理器清单中添加自定义类:ZCL_JSON_HANDLER,在登录数据中配置SAP的接口账号密码,最后激活服务,右键点击测试

 测试出现如下信息,表示内网环境下已配置成功。

接下来在POSTMAN中调用测试

在JAVA中测试:

JAVA中测试代码:

 1 package com.chenh.restful.test;
 2 import java.io.BufferedReader;
 3 import java.io.IOException;
 4 import java.io.InputStreamReader;
 5 import java.io.OutputStreamWriter;
 6 import java.net.HttpURLConnection;
 7 import java.net.MalformedURLException;
 8 import java.net.URL;
 9 import java.nio.charset.Charset;
10 import org.apache.tomcat.util.codec.binary.Base64;
11 
12 public class RFC_READ_TABLE {
13 
14     public static void main(String[] args) {
15         String URL = "http://xxxx.xxxx.xxxx.xxxx:8000/sap/bc/abapapi/";
16         String FNAME = "RFC_READ_TABLE";    
17         String json = "{\"QUERY_TABLE\":\"T001\",\"ROWCOUNT\":\"2\"}";
18 
19         String USERNAME = "XXXXXXX";
20         String PASSWORD = "XXXXXXX";
21         String auth = USERNAME + ":" + PASSWORD;
22         String authHeader = "Basic " + new String(Base64.encodeBase64(auth.getBytes(Charset.forName("US-ASCII"))));
23         HttpURLConnection conn = null;
24         OutputStreamWriter out = null;
25         BufferedReader in = null;
26         StringBuilder result = new StringBuilder();
27         String line;
28         try {
29             URL url = new URL(URL + FNAME);
30             conn = (HttpURLConnection) url.openConnection();
31             conn.setRequestProperty("Content-Type", "application/json");
32             conn.setRequestProperty("Accept", "application/json");
33             conn.setRequestProperty("Authorization", authHeader);
34             conn.setRequestMethod("POST");
35             conn.setConnectTimeout(6000);
36             conn.setReadTimeout(6000);
37             conn.setDoOutput(true);
38             conn.setDoInput(true);
39             out = new OutputStreamWriter(conn.getOutputStream());
40             out.write(json);
41             out.flush();
42             out.close();
43             if (200 == conn.getResponseCode()) {
44                 in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
45                 while ((line = in.readLine()) != null) {
46                     result.append(line);
47                 }
48             } else {
49                 System.out.println("发送失败:" + conn.getResponseCode());
50             }
51         } catch (MalformedURLException e) {
52             e.printStackTrace();
53         } catch (IOException e) {
54             e.printStackTrace();
55         }
56         System.out.println(result.toString());
57     }
58 }