abap json 序列化和反序列化

将abap结构转化成json,使用类/UI2/CL_JSON里面的方法SERIALIZE

1
2
3
DATA(LV_JSON) = /UI2/CL_JSON=>SERIALIZE( DATA          = XXXX
PRETTY_NAME = /UI2/CL_JSON=>PRETTY_MODE-NONE
COMPRESS = ABAP_TRUE ).

将json转变为abap结构,使用类/UI2/CL_JSON里面的方法DESERIALIZE

1
2
3
/UI2/CL_JSON=>DESERIALIZE( EXPORTING JSON = LV_RES
PRETTY_NAME = /UI2/CL_JSON=>PRETTY_MODE-NONE
CHANGING DATA = XXXX ).

但是在实际业务中,有可能第三方系统的报文,有固定的格式,比如全小写,后者驼峰形式的,那我们就要使用到方法里面的其他参数。

实现驼峰的两种方式

PRETTY_NAME
下面有一共有6个常量

1
2
3
4
5
6
7
8
9
CONSTANTS:
BEGIN OF PRETTY_MODE,
NONE TYPE CHAR1 VALUE ``,
LOW_CASE TYPE CHAR1 VALUE `L`, "输出都是小写
CAMEL_CASE TYPE CHAR1 VALUE `X`, "驼峰
EXTENDED TYPE CHAR1 VALUE `Y`, "驼峰形式的扩展吧
USER TYPE CHAR1 VALUE `U`, "
USER_LOW_CASE TYPE CHAR1 VALUE `C`, "
END OF PRETTY_MODE .

CAMEL_CASE 驼峰

如果对方需要使用驼峰形式的key,我们就要用到CAMEL_CASE常量,定义sap结构的时候用下划线_分割,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
TYPES: BEGIN OF TY_JSON,
STUNO TYPE STRING,
STU_NAME TYPE STRING,
STU_AGE TYPE STRING,
END OF TY_JSON.

DATA: LS_JSON TYPE TY_JSON.
DATA: LV_JSON TYPE STRING.

LS_JSON = VALUE #( STUNO = '1001' STU_NAME = 'ray' STU_AGE = '18' ).

LV_JSON = /UI2/CL_JSON=>SERIALIZE( DATA = LS_JSON
PRETTY_NAME = /UI2/CL_JSON=>PRETTY_MODE-CAMEL_CASE
COMPRESS = ABAP_TRUE ).

CL_DEMO_OUTPUT=>DISPLAY_JSON( LV_JSON ).

输出结果:

1
2
3
4
5
{
"stuno":"1001",
"stuName":"ray",
"stuAge":"18"
}

我们可以发现json已经自动将 下划线_ 删除了,如果json中就需要_,那我们可以用 双下划线 __ 来显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
TYPES: BEGIN OF TY_JSON,
STUNO TYPE STRING,
STU_NAME TYPE STRING,
STU__AGE TYPE STRING,
END OF TY_JSON.

DATA: LS_JSON TYPE TY_JSON.
DATA: LV_JSON TYPE STRING.

LS_JSON = VALUE #( STUNO = '1001' STU_NAME = 'ray' STU__AGE = '18' ).

LV_JSON = /UI2/CL_JSON=>SERIALIZE( DATA = LS_JSON
PRETTY_NAME = /UI2/CL_JSON=>PRETTY_MODE-CAMEL_CASE
COMPRESS = ABAP_TRUE ).

CL_DEMO_OUTPUT=>DISPLAY_JSON( LV_JSON ).

输出为:

1
2
3
4
5
{
"stuno":"1001",
"stuName":"ray",
"stu_age":"18"
}

MAPPING 表

第二种方式,就是使用MAPPING 表来替换 abap结构-字段和json-key,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
TYPES:
BEGIN OF NAME_MAPPING,
ABAP TYPE ABAP_COMPNAME,
JSON TYPE STRING,
END OF NAME_MAPPING .
TYPES:
NAME_MAPPINGS TYPE HASHED TABLE OF NAME_MAPPING WITH UNIQUE KEY ABAP .

DATA: LT_MAPPING TYPE NAME_MAPPINGS.

LT_MAPPING = VALUE #( ( ABAP = 'busCod' JSON = 'busCod' )
( ABAP = 'busMod' JSON = 'busMod' )
( ABAP = 'ccyNbr' JSON = 'ccyNbr' )
( ABAP = 'crtAcc' JSON = 'crtAcc' )
( ABAP = 'crtNam' JSON = 'crtNam' )
( ABAP = 'dbtAcc' JSON = 'dbtAcc' )
( ABAP = 'nusAge' JSON = 'nusAge' )
( ABAP = 'bnkFlg' JSON = 'bnkFlg' )
( ABAP = 'trsAmt' JSON = 'trsAmt' )
( ABAP = 'yurRef' JSON = 'yurRef' ) ).


LS_REQUEST-REQUEST-HEAD = VALUE #( FUNCODE = 'BB1PAYOP' USERID = 'N00336xxxx' REQID = '202003161123456780001fbxxxxx' ).

LS_REQUEST-REQUEST-BODY-BB1PAYBMX1 = VALUE #( ( BUSCOD = 'N02030' BUSMOD = '00003' ) ).
LS_REQUEST-REQUEST-BODY-BB1PAYOPX1 = VALUE #( ( CCYNBR = '10' CRTACC = '5719162xxxx401' CRTNAM = '欧弟专属测试户05'
DBTACC = '5719162xxxx401'
NUSAGE = '用途' BNKFLG = 'Y' TRSAMT = '1.05'
YURREF = '202008260078xxxx5' ) ).

LV_JSON = /UI2/CL_JSON=>SERIALIZE( DATA = LS_REQUEST
PRETTY_NAME = /UI2/CL_JSON=>PRETTY_MODE-LOW_CASE
COMPRESS = ABAP_TRUE
NAME_MAPPINGS = LT_MAPPING ).

输出的json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
"request": {
"head": {
"funcode": "BB1PAYOP",
"userid": "N003364302",
"reqid": "202003161123456780001fbxxxxx"
},
"body": {
"bb1paybmx1": [
{
"busMod": "00003",
"busCod": "N02030"
}
],
"bb1payopx1": [
{
"dbtAcc": "5719162xxxx401",
"crtAcc": "5719162xxxx401",
"crtNam": "欧弟专属测试户05",
"ccyNbr": "10",
"trsAmt": 1.05,
"bnkFlg": "Y",
"nusAge": "用途",
"yurRef": "202008260078xxxx5"
}
]
}
}
}

这样我们一样可以按照自己想要的格式,输出json

EXTENDED 驼峰扩展

与 CAMEL_CASE 的工作方式相同,但还具有用于编码特殊字符的扩展逻辑,例如:“.”、“@”、“~”等。如果您需要带有不允许用于 ABAP 数据的字符的 JSON 名称,则应使用组件名称。如果 JSON 名称中没有特殊字符,请不要使用它 - 与 CAMEL_CASE 模式相比,性能会更慢。示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 ABAP 名称 '__A__SCHEMA' 转换成 JSON 名称 '@schema'
编码规则(ABAP 名称 → JSON 名称):
'__E__' → '!'
'__N__' → '#'
'__D__' → '$'
'__P__' → '%'
'__M__' → '&'
'__S__' → '*'
'__H__' → '-'
'__T__' → '~'
'__L__' → '/'
'__C__' → ':'
'__V__' → '|'
'__A__' → '@'
'__O__' 或 '___' → '.'

更多/UI2/CL_JSON的使用说明请参照
https://wiki.scn.sap.com/wiki/display/Snippets/One+more+ABAP+to+JSON+Serializer+and+Deserializer