ABAP内表与JSON互转(续)

上一篇结尾我们提到,通过改造 CL_TREX_JSON_SERIALIZER 、CL_TREX_JSON_DESERIALIZER 这两个方法,来使程序更能适应外部系统的调用要求。

下面就是我们具体的改造操作:

CL_TREX_JSON_SERIALIZER

首先,我们使用事务码SE24打开CL_TREX_JSON_SERIALIZER这个类,拷贝一个新的类出来,命名为ZCL_TREX_JSON_SERIALIZER。

双击方法“RECURSE”,有两个地方需要做改动。

 

 

1.打开代码界面,在41行附近增加以下代码:

CONDENSE l_value."增加语句

 

 

2.在53行附近,注释掉原来的语句,改为下面的语句

concatenate '"' <abapcomp>-name '"' c_colon into l_value .

 

 RECURSE完整代码

 1 method RECURSE.
 2   data:
 3     l_type  type c ,
 4     l_comps type i ,
 5     l_lines type i ,
 6     l_index type i ,
 7     l_value type string .
 8   field-symbols:
 9     <itab> type any table ,
10     <comp> type any .
11 
12   describe field data type l_type components l_comps .
13 
14   if l_type = cl_abap_typedescr=>typekind_table .
15 *   itab -> array
16     append '[' to me->fragments .
17     assign data to <itab> .
18     l_lines = lines( <itab> ) .
19     loop at <itab> assigning <comp> .
20       add 1 to l_index .
21       recurse( <comp> ) .
22       if l_index < l_lines .
23         append c_comma to me->fragments .
24       endif .
25     endloop .
26     append ']' to fragments .
27   else .
28     if l_comps is initial .
29 *     field -> scalar
30 *     todo: format
31       l_value = data .
32       replace all occurrences of '\' in l_value with '\\' .
33       replace all occurrences of '''' in l_value with '\''' .
34       replace all occurrences of '"' in l_value with '\"' .
35       replace all occurrences of '&' in l_value with '\&' .
36       replace all occurrences of cl_abap_char_utilities=>cr_lf in l_value with '\r\n' .
37       replace all occurrences of cl_abap_char_utilities=>newline in l_value with '\n' .
38       replace all occurrences of cl_abap_char_utilities=>horizontal_tab in l_value with '\t' .
39       replace all occurrences of cl_abap_char_utilities=>backspace in l_value with '\b' .
40       replace all occurrences of cl_abap_char_utilities=>form_feed in l_value with '\f' .
41       CONDENSE l_value."增加语句
42       concatenate '"' l_value '"' into l_value .
43       append l_value to me->fragments .
44     else .
45 *     structure -> object
46       data l_typedescr type ref to cl_abap_structdescr .
47       field-symbols <abapcomp> type abap_compdescr .
48 
49       append '{' to me->fragments .
50       l_typedescr ?= cl_abap_typedescr=>describe_by_data( data ) .
51       loop at l_typedescr->components assigning <abapcomp> .
52         l_index = sy-tabix .
53         "concatenate <abapcomp>-name c_colon into l_value ."注释掉这句,改为下面的
54         concatenate '"' <abapcomp>-name '"' c_colon into l_value .
55         translate l_value to lower case .
56         append l_value to me->fragments .
57         assign component <abapcomp>-name of structure data to <comp> .
58         recurse( <comp> ) .
59         if l_index < l_comps .
60           append c_comma to me->fragments .
61         endif .
62       endloop .
63       append '}' to me->fragments .
64     endif .
65   endif .
66 endmethod.
View Code

第一个类改造完成。

 

CL_TREX_JSON_DESERIALIZER

同样,我们SE24打开类CL_TREX_JSON_DESERIALIZER,拷贝一个新的类ZCL_TREX_JSON_DESERIALIZER。

双击方法“DESERIALIZE_OBJECT”,需要改动的有两个地方。

 

 

1.注释第28行,换成下面的语句:

FIND REGEX '"(\w+)\s*":' IN SECTION OFFSET offset OF json

 

 

2.在44行附近新增下面的语句:

IF sy-subrc <> 0."新增--S
          CONTINUE.
ENDIF.          "新增--E

 

 

DESERIALIZE_OBJECT完整代码

 1 METHOD deserialize_object.
 2   DATA:
 3     l_node_type TYPE REF TO cl_abap_typedescr,
 4     l_ref       TYPE REF TO object.
 5 
 6   ADD 1 TO offset . "skip {
 7 
 8   l_node_type = cl_abap_typedescr=>describe_by_data( node ) .
 9 
10 * prepare for dynamic access
11   CASE l_node_type->kind .
12     WHEN cl_abap_typedescr=>kind_ref .
13       l_ref = node .
14     WHEN cl_abap_typedescr=>kind_struct .
15 
16     WHEN OTHERS .
17       RAISE EXCEPTION TYPE cx_trex_serialization .
18   ENDCASE .
19 
20   DATA:
21     l_done TYPE abap_bool,
22     l_len  TYPE i,
23     l_name TYPE string.
24 
25 * handle each component
26   WHILE l_done = abap_false .
27     "find next key
28     FIND REGEX '"(\w+)\s*":' IN SECTION OFFSET offset OF json"find regex '(\w+)\s*:' in section offset offset of json  注释原有的,换成现在的语句
29       MATCH OFFSET offset MATCH LENGTH l_len
30       SUBMATCHES l_name .
31     IF sy-subrc <> 0 .
32       RAISE EXCEPTION TYPE cx_trex_serialization .
33     ENDIF .
34     ADD l_len TO offset .
35 
36     FIELD-SYMBOLS <comp> TYPE any .
37 
38 *   dynamic binding to component
39     TRANSLATE l_name TO UPPER CASE .
40     CASE l_node_type->kind .
41       WHEN cl_abap_typedescr=>kind_ref .
42         ASSIGN l_ref->(l_name) TO <comp> .
43       WHEN cl_abap_typedescr=>kind_struct .
44         ASSIGN COMPONENT l_name OF STRUCTURE node TO <comp> .
45         IF sy-subrc <> 0."新增--S
46           CONTINUE.
47         ENDIF.          "新增--E
48       WHEN OTHERS .
49         RAISE EXCEPTION TYPE cx_trex_serialization .
50     ENDCASE .
51 
52     DATA:
53       l_comp_type TYPE REF TO cl_abap_typedescr,
54       l_ref_type  TYPE REF TO cl_abap_refdescr.
55 
56 *   check component type
57     l_comp_type = cl_abap_typedescr=>describe_by_data( <comp> ) .
58     CASE l_comp_type->kind .
59 *     create instance if it's an oref
60       WHEN cl_abap_typedescr=>kind_ref .
61         l_ref_type ?= l_comp_type .
62         l_comp_type = l_ref_type->get_referenced_type( ) .
63         CREATE OBJECT <comp> TYPE (l_comp_type->absolute_name) .
64     ENDCASE .
65 
66 *   deserialize current component
67     deserialize_node(
68       EXPORTING
69         json = json
70       CHANGING
71         offset = offset
72         node = <comp> ) .
73 
74     FIND REGEX ',|\}' IN SECTION OFFSET offset OF json MATCH OFFSET offset .
75     IF sy-subrc <> 0 .
76       RAISE EXCEPTION TYPE cx_trex_serialization .
77     ENDIF .
78 
79     IF json+offset(1) = '}' .
80       l_done = abap_true .
81     ENDIF .
82     ADD 1 TO offset .
83   ENDWHILE .
84 
85 ENDMETHOD.
View Code

 

至此,两个类均改造完成,相应的在调用时使用我们拷贝出来的Z开头的这个类。

posted @ 2021-06-21 15:03  LouiseMa  阅读(779)  评论(0)    收藏  举报