ABAP小白开发操作手册+(九)ABAP调用http
开发类型:
新增ABAP通过调用http的方式来发送业务数据到其他系统
开发申请:
(这里业务的开发申请没写完整SAP对应外部系统字段的对应关系,没关系,我们可以看接口文档)
外围系统提供的接口文档:
(这一part的参数有点长,大家看看得了,不用太在意,把这个外围系统提供的参数列出来,只是为了体现参数的一些结构,方便大家对比后面我们在开发过程中,如何进行SAP参数的设置)
接口地址:
测试机: http://123456/rdmCalled/forSap/poInfo
正式机: http://123456/rdmCalled/forSap/poInfo
请求方式:
POST
入参类型:
["aplication/json"]
响应类型:
["application/json"]
请求参数:
入参示例:
{
"detailInfoList": [
{
"count": 2,
"materialNo": "m001",
"materialName": "物料001",
"rowNo": "1",
"status": 1,
"taxRate": 0,
"totalPrice": 10,
"unitPrice": 5
}
],
"orderDate": "2024-04-28 00:00:00",
"poNo": "po001",
"prNo": "pr001",
"projectCode": "HKC20230524001"
}
响应状态:
状态码 | 说明 |
200 | 成功 |
500 | 异常 |
503 | 服务不正常 |
403 | 无权限 |
401 | 未登录 |
响应参数:
参数名称 | 参数说明 | 类型 | schema |
code | 响应状态码 (成功200, 失败500) | integer(int32) | integer(int32) |
data | 需要返回的数据(该接口可忽略) | string | |
detailMsg | 详细的消息内容,一般用于显示错误的原因 | string | detailMsg |
message | 返回信息 | string | |
show | 在浏览器端的默认信息中是否显示(该接口可忽略) | boolean | |
success | 是否成功 | boolean |
响应示例:
成功:
{
"success": true,
"message": "添加PO单信息成功; PO单号【po001】",
"detailMsg": "",
"show": true,
"code": 200,
"data": null
}
失败:
{
"success": false,
"message": "入参校验失败!",
"detailMsg": "项目编号不能为空; ",
"show": true,
"code": 500,
"data": null
}
开发步骤:
有点多,我先把代码粘贴上来
因为本质上还是接口,所以我们还是用事务代码SE37进行开发,进行导入导出参数的设置、源代码编写,今天太晚了,明天重新编辑一下
FUNCTION ZZMM_PO_TO_RDM_TEST.
*"----------------------------------------------------------------------
*"*"本地接口:
*" IMPORTING
*" VALUE(I_FRDAT) TYPE FRGDT
*" VALUE(I_EBELN) TYPE EBELN
*" VALUE(I_BANFN) TYPE BANFN
*" VALUE(I_ZZRDMNO) TYPE ZERDMNO
*" EXPORTING
*" VALUE(E_RTYPE) TYPE BAPI_MTYPE
*" VALUE(E_RTYMSG) TYPE BAPI_MSG
*" TABLES
*" T_DATA STRUCTURE ZSMM0093
*"----------------------------------------------------------------------MACRO_SAVE_LOG_BEFORE_PROC.MACRO_SAVE_LOG_AFTER_PROC 'IN'.DATA LO_DATA TYPE REF TO DATA.DATA LV_ECS_JSON_REQ TYPE STRING.DATA: LV_ECS_JSON_RES TYPE STRING,LV_URL TYPE STRING,
* LV_URL TYPE CHAR200,LV_MSG TYPE STRING,LV_TYPE TYPE BAPI_MTYPE.DATA GS_ECS_REQ TYPE zsMM0097.DATA GS_ECS_RET TYPE zsMM0098.DATA GT_ECS_INV_MAPPING TYPE /UI2/CL_JSON=>NAME_MAPPINGS.DATA GT_ECS_MAPPING_RET TYPE /UI2/CL_JSON=>NAME_MAPPINGS.GS_ECS_REQ-ORDERDATE = I_FRDAT.GS_ECS_REQ-PRNO = I_BANFN.GS_ECS_REQ-pOno = i_EBELN.GS_ECS_REQ-PROJECTCODE = I_ZZRDMNO.APPEND LINES OF t_DATA[] TO GS_ECS_REQ-DETAILS.LO_DATA = REF #( GS_ECS_REQ ).IF LO_DATA IS NOT BOUND.MACRO_SAVE_LOG_AFTER_PROC 'OUT'.RETURN.ENDIF."获取接口地址:配置成后台表SELECT SINGLE * FROM ZTMMURLWHERE Zname = 'PO_URL_RDM'INTO @DATA(LS_ZTMMURL).IF LS_ZTMMURL-ZVAL IS INITIAL.E_RTYPE = 'E'.E_RTYMSG = '接口地址未配置,请到ZTMMURL表中配置接口地址'.MACRO_SAVE_LOG_AFTER_PROC 'OUT'.RETURN.ENDIF.LV_URL = CONV CHAR200( LS_ZTMMURL-ZVAL ).CONDENSE LV_URL NO-GAPS.
*设置JSON字符转换GT_ECS_INV_MAPPING = VALUE #(( ABAP = 'DETAILS' JSON = 'detailInfoList' )
( ABAP = 'BNFPO' JSON = 'prRowNo' )
( ABAP = 'EBELP' JSON = 'rowNo' )
( ABAP = 'MATNR' JSON = 'materialNo' )
( ABAP = 'TXZ01' JSON = 'materialName' )
( ABAP = 'LOEKZ' JSON = 'status' )
( ABAP = 'NETPR' JSON = 'unitPrice' )
( ABAP = 'BRTWR' JSON = 'totalPrice' )
( ABAP = 'MENGE' JSON = 'count' )
( ABAP = 'ORDERDATE' JSON = 'orderDate' )
( ABAP = 'PONO' JSON = 'poNo' )
( ABAP = 'PRNO' JSON = 'prNo')
( ABAP = 'PROJECTCODE' JSON = 'projectCode' )).GT_ECS_MAPPING_RET = VALUE #(( ABAP = 'code' JSON = 'code')( ABAP = 'data' JSON = 'data')( ABAP = 'detailmsg' JSON = 'detailMsg')( ABAP = 'message' JSON = 'message')( ABAP = 'show' JSON = 'show')( ABAP = 'success' JSON = 'success')).
*将ABAP数据转换为JSON格式CALL METHOD /UI2/CL_JSON=>SERIALIZEEXPORTINGDATA = LO_DATA
* COMPRESS = 'X'PRETTY_NAME = /UI2/CL_JSON=>PRETTY_MODE-LOW_CASENAME_MAPPINGS = GT_ECS_INV_MAPPINGRECEIVINGR_JSON = LV_ECS_JSON_REQ.*创建CLIENTDATA:lo_http_client TYPE REF TO if_http_client.DATA l_resp TYPE string.
DATA:tt_headfield TYPE TIHTTPNVP .CALL METHOD cl_http_client=>create_by_urlEXPORTINGurl = lv_url"APIIMPORTINGclient = lo_http_clientEXCEPTIONSargument_not_found = 1plugin_not_active = 2internal_error = 3OTHERS = 4.IF sy-subrc <> 0.MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgnoWITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO E_RTYMSG.E_RTYMSG = '创建client错误,错误信息: ' && E_RTYMSG.E_RTYPE = 'E'.RETURN.ENDIF.lo_http_client->request->set_method('POST').CALL METHOD lo_http_client->request->if_http_entity~set_header_fieldEXPORTINGname = 'Content-Type'value = 'application/json'.IF tt_headfield[] IS NOT INITIAL.CALL METHOD lo_http_client->request->if_http_entity~set_header_fieldsEXPORTINGfields = tt_headfield[].ENDIF.IF LV_ECS_JSON_REQ IS NOT INITIAL.DATA(l_conten_len) = strlen( LV_ECS_JSON_REQ ).CALL METHOD lo_http_client->request->if_http_entity~set_cdataEXPORTINGdata = LV_ECS_JSON_REQoffset = 0length = l_conten_len.ENDIF.
*发送请求CALL METHOD lo_http_client->sendEXPORTINGtimeout = 300EXCEPTIONShttp_communication_failure = 1http_invalid_state = 2http_processing_failed = 3http_invalid_timeout = 4OTHERS = 5.IF sy-subrc <> 0.MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgnoWITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO E_RTYMSG.E_RTYMSG = '发送请求错误,错误信息: ' && E_RTYMSG.E_RTYPE = 'E'.CALL METHOD lo_http_client->close.RETURN.ENDIF.
*返回请求CALL METHOD lo_http_client->receiveEXCEPTIONShttp_communication_failure = 1http_invalid_state = 2http_processing_failed = 3OTHERS = 4.IF sy-subrc <> 0.MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgnoWITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO E_RTYMSG.E_RTYMSG = '返回请求错误,错误信息: ' && E_RTYMSG.e_Rtype = 'E'.CALL METHOD lo_http_client->close.RETURN.ENDIF.
*转换后的JSON字符串赋值CALL METHOD lo_http_client->response->if_http_entity~get_cdataRECEIVINGdata = l_resp.LV_ECS_JSON_RES = l_resp.
*关闭请求CALL METHOD lo_http_client->close.
*读取远程服务器返回的处理结果LO_DATA = REF #( GS_ECS_RET ).CALL METHOD /UI2/CL_JSON=>DESERIALIZEEXPORTINGJSON = LV_ECS_JSON_RESNAME_MAPPINGS = GT_ECS_MAPPING_RETCHANGINGDATA = LO_DATA.SEARCH LV_ECS_JSON_RES FOR 'false'.GS_ECS_RET-SUCCESS = XSDBOOL( SY-SUBRC NE 0 ).IF GS_ECS_RET-SUCCESS EQ ABAP_TRUE.E_RTYPE = 'S'.ELSE.E_RTYPE = 'E'.ENDIF.E_RTYMSG = GS_ECS_RET-MESSAGE.MACRO_SAVE_LOG_AFTER_PROC 'OUT'.ENDFUNCTION.