欢迎来到萧静默的博客

书山有路勤为径,学海无涯苦作舟。

关于ABAP调用LO_HTTP_CLIENT->RESPONSE->GET_DATA( )接收到乱码的解决方案

最近在处理SAP与外围系统的数据交互,其中发现涉及了几个要点。

1、abap转json发送。

2、json转abap接收。

3、接收到的json里的中文是乱码的问题。

 

1、SAP发送数据给外围系统时,有的要求要先获取token,有的不需要,笔者这里使用的是需要先获取token的情况,

此处获取token,外围系统会提供一个API,用户名,和密码,你要根据这三样去获取一个临时token。

这个时候你可以先用postman调用一下,看是否能正确获取。如果可以的话,开始组织ABAP代码,如果外围系统不多,可以直接写死API,用户名,和密码,

如果外围系统多的话,建议建立一个自建表,根据不同的外围系统名称去获取对应的API,用户名,和密码。这里以写死为例,代码如下:

"获取token
DATA:
  LO_HTTP_CLIENT TYPE REF TO IF_HTTP_CLIENT,
  LV_LEN         TYPE I,
  CONV           TYPE REF TO CL_ABAP_CONV_IN_CE.
DATA:LV_QUE_URL TYPE STRING.
DATA:LV_QUE_STR TYPE STRING.
DATA: LX_RESULT TYPE XSTRING,
      LV_RESULT TYPE STRING.
DATA:V_I TYPE I,
     V_S TYPE STRING.

LV_QUE_URL = 'http://IP:8088/seeyon/rest/token'.

LV_QUE_STR = '{ "userName": "restsap",  "password": "582420a8-e84e-4ee9-87fd-82289ce9f46b" }'.

FREE:LO_HTTP_CLIENT.

CL_HTTP_CLIENT=>CREATE_BY_URL(
EXPORTING
  URL                = LV_QUE_URL
*      ssl_id             = 'ANONYM'
IMPORTING
  CLIENT             = LO_HTTP_CLIENT
EXCEPTIONS
  ARGUMENT_NOT_FOUND = 1
  PLUGIN_NOT_ACTIVE  = 2
  INTERNAL_ERROR     = 3
  OTHERS             = 4 ).

"设定传输请求内容格式以及编码格式
LO_HTTP_CLIENT->REQUEST->SET_CONTENT_TYPE( CONTENT_TYPE = 'application/json; charset=utf-8' ).
"设定调用服务
LO_HTTP_CLIENT->REQUEST->SET_METHOD( IF_HTTP_REQUEST=>CO_REQUEST_METHOD_POST ).

LO_HTTP_CLIENT->RESPONSE->IF_HTTP_ENTITY~SET_CONTENT_TYPE( CONTENT_TYPE = 'application/json' ).

LV_LEN = STRLEN( LV_QUE_STR ).

CALL METHOD LO_HTTP_CLIENT->REQUEST->SET_CDATA
  EXPORTING
    DATA   = LV_QUE_STR
    OFFSET = 0
    LENGTH = LV_LEN.

LO_HTTP_CLIENT->SEND(
EXCEPTIONS
  HTTP_COMMUNICATION_FAILURE = 1
  HTTP_INVALID_STATE         = 2 ).

LO_HTTP_CLIENT->RECEIVE(
EXCEPTIONS
  HTTP_COMMUNICATION_FAILURE = 1
  HTTP_INVALID_STATE         = 2
  HTTP_PROCESSING_FAILED     = 3 ).
IF SY-SUBRC <> 0.
ENDIF.



CLEAR LV_RESULT .
LX_RESULT = LO_HTTP_CLIENT->RESPONSE->GET_DATA( ).

LO_HTTP_CLIENT->RESPONSE->GET_STATUS(
IMPORTING
  CODE   = V_I
  REASON = V_S ).

CALL METHOD LO_HTTP_CLIENT->CLOSE.

CHECK LX_RESULT IS NOT INITIAL.

CALL METHOD CL_ABAP_CONV_IN_CE=>CREATE
  EXPORTING
    ENCODING = '8400'
  RECEIVING
    CONV     = CONV.
CONV->CONVERT( EXPORTING INPUT = LX_RESULT IMPORTING DATA = LV_RESULT ).

"定义下和回传结构一致的ABAP结构
DATA: BEGIN OF LS_KV,
        BINDINGUSER TYPE STRING,
        ID          TYPE STRING,
      END OF LS_KV.

CHECK LV_RESULT IS NOT INITIAL.
CALL METHOD /UI2/CL_JSON=>DESERIALIZE
  EXPORTING
    JSON        = LV_RESULT
    PRETTY_NAME = /UI2/CL_JSON=>PRETTY_MODE-CAMEL_CASE
  CHANGING
    DATA        = LS_KV.

 2、根据获取到的token,发送外围系统数据。

DATA:LV_QUE_URL1 TYPE STRING.
"这里是网址拼接TOKEN的方式,有时候是传表头的方式,根据实际情况处理 LV_QUE_URL1
= 'http://IP:8088/seeyon/rest/pidaoResource/pidao?token='&& LS_KV-ID. "定义要传输的内表格式,需要转为json DATA:LV_QUE_STR1 TYPE STRING. TYPES: BEGIN OF T_DATAS2, KEY TYPE STRING, AMOUNT TYPE STRING, END OF T_DATAS2. TYPES: TT_DATAS2 TYPE STANDARD TABLE OF T_DATAS2 WITH DEFAULT KEY. DATA:LT_DATA TYPE STANDARD TABLE OF T_DATAS2, LS_DATA TYPE T_DATAS2. "这里可以换成取数模式 LS_DATA-KEY = '111'. LS_DATA-AMOUNT = '1000'. APPEND LS_DATA TO LT_DATA. CLEAR:LS_DATA. LS_DATA-KEY = '222'. LS_DATA-AMOUNT = '2000'. APPEND LS_DATA TO LT_DATA. TYPES: BEGIN OF T_JSON1, ACTION TYPE STRING, DATAS TYPE TT_DATAS2, END OF T_JSON1. DATA:LT_OUT TYPE STANDARD TABLE OF T_JSON1, LS_OUT TYPE T_JSON1. LS_OUT-ACTION = 'check'. LS_OUT-DATAS = LT_DATA. APPEND LS_OUT TO LT_OUT. ***内表->JSON CALL METHOD /UI2/CL_JSON=>SERIALIZE EXPORTING DATA = LS_OUT COMPRESS = ABAP_FALSE PRETTY_NAME = /UI2/CL_JSON=>PRETTY_MODE-LOW_CASE RECEIVING R_JSON = LV_QUE_STR1. *LV_QUE_STR1 = '{ "action": "check", "datas":[ { "key":"111","amount":"1000"},{ "key":"222","amount":"2000"}] }'. FREE:LO_HTTP_CLIENT. CL_HTTP_CLIENT=>CREATE_BY_URL( EXPORTING URL = LV_QUE_URL1 * ssl_id = 'ANONYM' IMPORTING CLIENT = LO_HTTP_CLIENT EXCEPTIONS ARGUMENT_NOT_FOUND = 1 PLUGIN_NOT_ACTIVE = 2 INTERNAL_ERROR = 3 OTHERS = 4 ). "设定传输请求内容格式以及编码格式 LO_HTTP_CLIENT->REQUEST->SET_CONTENT_TYPE( CONTENT_TYPE = 'application/json; charset=utf-8' ). "设定调用服务 LO_HTTP_CLIENT->REQUEST->SET_METHOD( IF_HTTP_REQUEST=>CO_REQUEST_METHOD_POST ). LO_HTTP_CLIENT->RESPONSE->IF_HTTP_ENTITY~SET_CONTENT_TYPE( CONTENT_TYPE = 'application/json' ). CLEAR:LV_LEN. LV_LEN = STRLEN( LV_QUE_STR1 ). CALL METHOD LO_HTTP_CLIENT->REQUEST->SET_CDATA EXPORTING DATA = LV_QUE_STR1 OFFSET = 0 LENGTH = LV_LEN. LO_HTTP_CLIENT->SEND( EXCEPTIONS HTTP_COMMUNICATION_FAILURE = 1 HTTP_INVALID_STATE = 2 ). LO_HTTP_CLIENT->RECEIVE( EXCEPTIONS HTTP_COMMUNICATION_FAILURE = 1 HTTP_INVALID_STATE = 2 HTTP_PROCESSING_FAILED = 3 ). IF SY-SUBRC <> 0. ENDIF. CLEAR:V_I , V_S . CLEAR LV_RESULT . LX_RESULT = LO_HTTP_CLIENT->RESPONSE->GET_DATA( ). LO_HTTP_CLIENT->RESPONSE->GET_STATUS( IMPORTING CODE = V_I REASON = V_S ). CALL METHOD LO_HTTP_CLIENT->CLOSE.

3、解析外围系统返回的数据

CHECK LX_RESULT IS NOT INITIAL.

"解析JSON串

CLEAR:LV_RESULT.
CALL METHOD CL_ABAP_CONV_IN_CE=>CREATE
  EXPORTING
    ENCODING = '4110'
  RECEIVING
    CONV     = CONV.
CONV->CONVERT( EXPORTING INPUT = LX_RESULT IMPORTING DATA = LV_RESULT ).

CHECK LV_RESULT IS NOT INITIAL.

"定义下和回传结构一致的ABAP结构
TYPES: BEGIN OF T_INPUT_SON,
         AMOUNT  TYPE STRING,
         CODE    TYPE STRING,
         MESSAGE TYPE STRING,
         KEY     TYPE STRING,
       END OF T_INPUT_SON.
TYPES: TT_INPUT_SON TYPE STANDARD TABLE OF T_INPUT_SON WITH DEFAULT KEY.

DATA:LT_DATA_SON TYPE STANDARD TABLE OF T_INPUT_SON,
     LS_DATA_SON TYPE T_INPUT_SON.

TYPES: BEGIN OF T_ABAP,
         SUCCESSLIST TYPE TT_INPUT_SON,
       END OF T_ABAP.

DATA:LT_INPUT TYPE STANDARD TABLE OF T_ABAP,
     LS_INPUT TYPE T_ABAP.

CALL METHOD /UI2/CL_JSON=>DESERIALIZE
  EXPORTING
    JSON        = LV_RESULT
    PRETTY_NAME = /UI2/CL_JSON=>PRETTY_MODE-CAMEL_CASE
  CHANGING
    DATA        = LS_INPUT.

LOOP AT LS_INPUT-SUCCESSLIST INTO DATA(LS_INPUT-SUCCESSLIST_1).
  WRITE:/ LS_INPUT-SUCCESSLIST_1-KEY,/ LS_INPUT-SUCCESSLIST_1-AMOUNT.

ENDLOOP.

上面的4110怎么来的呢,这个是根据外围系统发送的字符格式来做对应的处理。

去SAP里查看TCP00的表

 

 

 

 这里查出UTF-8的SAP 字符集标识为4110,所以使用这个进行转换下。

当然这个类/UI2/CL_JSON的序列化及反序列化网上都有,其中有个注意点是可能外围系统是驼峰命名,这里需要加入参数PRETTY_NAME,里面有大小写,驼峰等形式。

posted @ 2023-03-06 10:09  萧静默  阅读(944)  评论(0编辑  收藏  举报