【SAP PO】SAP PO 接口配置完整教程之二REST服务对接
SAP PO 接口配置完整教程之二REST服务对接
SAP PO 接口配置完整教程之二REST服务对接
本示例以SAP端作为请求端,通过调用封装了外部Rest服务的Sproxy代理类方法,实现与外部服务的对接。
1、了解服务协议
外部服务,由对接方系统提供。
现在主流的服务形式为Restful接口服务,需要使用JSON 数据格式、UTF8 编码。
这里我们以一个SAP推送采购需求到SRM系统的实际案例来进行举例说明。
1.1、服务通讯协议
(1)接口访问方式
请求数据类型:JSON
请求方式:POST
认证方式:Oauth 2.0
传输协议:https
(2)接口认证方式
在每次主动调用SRM开放平台接口时需要带上AccessToken参数,开放平台会根据此次访问的 AccessToken,校验访问的合法性以及所对应的权限并返回相应的结果。
AccessToken的默认有效期为1小时,调用方可定时更新自己本地缓存的token。
设置AccessToken有两种方式,推荐使用第一种,如下所示:
A:在httpHeaders里面设置AccessToken
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Authorization", "Bearer " + accessToken);
B:在调用地址后面带上AccessToken
https://*******/sitf/v1/rest/operation-units/conversion-operation-unit?access_token=5e0b05ef-ea2e-4cd8-8a90-2663498e9d87
获取Access Token
① 简要描述:调用该接口,获取token授权,token将作为其他接口的授权凭证。
② 请求方式:POST
③ 请求URL:/oauth/oauth/token
④ 请求参数示例:
https://*******/oauth/oauth/token?grant_type=client_credentials&client_id=*******&client_secret=******&scope=default
请求参数说明
参数名称 | 类型 | 非空 | 描述 |
---|---|---|---|
grant_type | String | 是 | 授权模式,固定值client_credentials |
client_id | String | 是 | 即对接账号(由服务方提供) |
client_secret | String | 是 | 客户端密钥(由服务方提供) |
scope | String | 是 | 作用域,固定值default |
⑤ 反馈示例
正确返回值
{
"access_token": "97eb08ad-8c86-459f-9526-905caebe2958",
"token_type": "Bearer",
"expires_in": 2263,
"scope": "default"
}
错误返回值
{
"error": "invalid_grant",
"error_description": "Bad credentials"
}
反馈参数说明
参数名称 | 类型 | 非空 | 描述 |
---|---|---|---|
access_token | String | 是 | 访问令牌,用于业务接口调用。 |
token_type | String | 是 | Token类型 |
expires_in | Integer | 是 | access_token的有效期,单位:秒 |
scope | String | 是 | 作用域 |
(3)标准请求结构说明
请求body由两部分组成,一部分是"header"信息(并非httpHeader,每个接口格式固定),一部分是"body"信息(存放的动态业务数据,每个接口视具体接口字段而定),如下所示
{
"header":{
"applicationCode":"",
"applicationGroupCode":"",
"batchCount":"",
"batchNum":"",
"externalSystemCode":"",
"interfaceCode":"",
"userName":""
},
"body":[
{
"sourceCode":"testFiled",
"esOuCode":"testFiled",
"erpCreationDate":"2019-09-16 03:01:50",
"erpLastUpdateDate":"2019-09-16 03:01:50",
"enabledFlag":1,
"esOuId":"testFiled",
"ouName":"testFiled"
}
]
}
请求参数说明
字段 | 字段类型 | 是否必填 | 描述 | 备注 |
---|---|---|---|---|
applicationGroupCode | String | 是 | 应用组 | SRM提供,随着对接环境不同会变化 |
applicationCode | String | 是 | 应用 | SRM提供,随着对接环境不同会变化 |
batchCount | String | 否 | 数据量 | 对方系统提供,可不传 |
batchNum | String | 是 | 批次号 | 对方系统提供,不超过20位递增的数字,建议时间戳 |
externalSystemCode | String | 是 | 外部系统 | SRM提供,固定值 |
interfaceCode | String | 是 | 接口编码 | SRM提供,不同接口编码不同 |
userName | String | 是 | 用户名 | SRM提供,SRM子账户名,随着对接环境不同会变化 |
(4)标准反馈结构说明
SRM接口的反馈结构是固定的标准格式,分为批次响应结果(本次请求的响应结果)和单据执行结果(传输的具体单据的执行响应结果),如下所示:
{
"batchNum":"",
"executeResult":"PART",
"responseMessage":"SSS",
"responseStatus":"SUCCESS",
"restResponseDtlDTOList":[
{
"documentCode":"SS",
"documentId":1,
"responseMessage":"MM",
"responseStatus":"SUCCESS"
},
{
"documentCode":"BB",
"documentId":2,
"responseMessage":"",
"responseStatus":"ERROR"
}
]
}
反馈参数说明
字段 | 字段类型 | 描述 | 备注 |
---|---|---|---|
batchNum | String | 批次号 | 请求的批次号 |
responseStatus | String | 程序执行状态 | ERROR:失败,SUCCESS:成功;状态为ERROR说明整批数据程序执行异常,无需关心明细响应结构。状态为SUCCESS,需要从restResponseDtlDTOList中获取具体每条数据的执行状态 |
responseMessage | String | 错误信息 | |
executeResult | String | 执行结果 | SUCCESS:数据全部执行成功,FAILED:数据全部执行失败,PART:数据部分成功部分失败 |
restResponseDtlDTOList
字段 | 字段类型 | 描述 | 备注 |
---|---|---|---|
documentId | Long | erp业务单据唯一性标识 | 暂无使用 |
documentCode | String | erp业务单据唯一性标识 | 对应接口的唯一性字段 |
responseStatus | String | 执行状态 | SUCCESS:成功,ERROR:失败(当前此笔单据执行的状态) |
responseMessage | String | 错误信息 | 当前此笔单据执行产生的异常信息,如果状态为SUCCESS此处无值,如果为ERROR,此处有具体报错信息 |
1.2、具体接口协议
(1)接口地址:https://gateway.dev.isrm.going-link.com/sitf/v1/rest/forecast/receiver-data
(2)请求报文结构:
{
"header": {
"applicationCode": "服务方提供",
"applicationGroupCode":"服务方提供",
"batchCount":"此批次数据条数",
"batchNum":"递增且唯一的少于20位的数字,建议时间戳",
"externalSystemCode":"服务方提供的外部系统CODE",
"interfaceCode":"服务方提供",
"userName": "服务方提供"
},
"body": [
{
"esFcstHeaderId": "",
"esFcstNum": "2200001003361000001101421010",
"lineNum": "1",
"sourceCode": "SAP",
"fcstStartDate": "2022-01-01",
"esItemId": "",
"esItemCode": "000000100000110142",
"esSupplierId": "",
"esSupplierCode": "0000100336",
"esCategoryId": "",
"esCategoryCode": "",
"esOuId": "",
"esOuCode": "1000",
"esUomCode": "PCS",
"esUomName": "",
"esAgentId": "",
"esAgentCode": "",
"esPurchaseOrgId": " ",
"esPurchaseOrgCode": "",
"esInvOrganizationId": " ",
"esInvOrganizationCode": "1010",
"updateSelectiveFlag": "1",
"deliveryPlan": "",
"forecastLines": [
{
"fcstLineType": "MONTH",
"fcstSeq": "3",
"fcstDate": "month3",
"fcstQuantity": "30",
"fcstLineDetails": [
{
"fcstDeliveryDate":"2022-03-15",
"fcstQuantity": 30.0,
"purchaserRemark": "采购方备注"
}
]
}
]
}
]
}
(3)返回报文结构:同标准结构。
1.3、接口服务测试
首先确保服务能够被正常访问,我们可以使用postman工具来做接口测试。
接口测试通过,第三方服务准备就绪,接下来就开始PO端的配置。
2、PO端接口配置
2.1、PO端ESR配置
(1)登录PO,点击 Enterprise Services Builder,进入Java版ESB配置客户端
(2)创建 Namespace (仅首次需要)
在 SC_ERP(对应SAP系统)下新建 Namespace,右键→New→Namespace
输入 Namespace 名称,点击 Create
(3)在 Namespace 下创建文件夹,右键→Create Folder
修改为自己所需的文件夹名称,如:
(4)定义 ED(External Definition)
首先,定义报文结构 xsd文件
请求报文:ED_SRM_FORECAST_REQ.xsd
<?xml version="1.0" encoding="utf-8"?>
<schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema">
<element name="ED_SRM_FORECAST_REQ">
<complexType>
<sequence>
<element name="header" minOccurs="0">
<complexType>
<sequence>
<element name="applicationCode" type="string" minOccurs="0"/>
<element name="applicationGroupCode" type="string" minOccurs="0"/>
<element name="batchCount" type="string" minOccurs="0"/>
<element name="batchNum" type="string" minOccurs="0"/>
<element name="externalSystemCode" type="string" minOccurs="0"/>
<element name="interfaceCode" type="string" minOccurs="0"/>
<element name="password" type="string" minOccurs="0"/>
<element name="userName" type="string" minOccurs="0"/>
</sequence>
</complexType>
</element>
<element name="body" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="esFcstHeaderId" type="string" minOccurs="0"/>
<element name="esFcstNum" type="string" minOccurs="0"/>
<element name="lineNum" type="string" minOccurs="0"/>
<element name="sourceCode" type="string" minOccurs="0"/>
<element name="fcstStartDate" type="string" minOccurs="0"/>
<element name="esItemCode" type="string" minOccurs="0"/>
<element name="esSupplierCode" type="string" minOccurs="0"/>
<element name="esCategoryCode" type="string" minOccurs="0"/>
<element name="esOuCode" type="string" minOccurs="0"/>
<element name="esUomCode" type="string" minOccurs="0"/>
<element name="esAgentCode" type="string" minOccurs="0"/>
<element name="esPurchaseOrgCode" type="string" minOccurs="0"/>
<element name="esInvOrganizationCode" type="string" minOccurs="0"/>
<element name="updateSelectiveFlag" type="string" minOccurs="0"/>
<element name="forecastLines" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="fcstLineType" type="string" minOccurs="0"/>
<element name="fcstSeq" type="string" minOccurs="0"/>
<element name="fcstDate" type="string" minOccurs="0"/>
<element name="fcstQuantity" type="string" minOccurs="0"/>
<element name="fcstLineDetails" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="fcstDeliveryDate" type="string" minOccurs="0"/>
<element name="fcstQuantity" type="string" minOccurs="0"/>
<element name="purchaserRemark" type="string" minOccurs="0"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
响应报文:ED_SRM_FORECAST_RESP.xsd
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.yankon.com/xi/SRM" targetNamespace="http://www.yankon.com/xi/SRM">
<xsd:element name="MT_SRM_RESP" type="DT_SRM_RESP" />
<xsd:complexType name="DT_SRM_RESP">
<xsd:sequence>
<xsd:element name="batchNum" type="xsd:string" minOccurs="0" />
<xsd:element name="responseStatus" type="xsd:string" minOccurs="0" />
<xsd:element name="responseMessage" type="xsd:string" minOccurs="0" />
<xsd:element name="executeResult" type="xsd:string" minOccurs="0" />
<xsd:element name="restResponseDtlDTOList" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="documentId" type="xsd:string" minOccurs="0" />
<xsd:element name="documentCode" type="xsd:string" minOccurs="0" />
<xsd:element name="responseStatus" type="xsd:string" minOccurs="0" />
<xsd:element name="responseMessage" type="xsd:string" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
说明:
① xml节点有无“xsd:”,没有区别。
② 响应结构与请求结构,前几行定义方式不一致,是由于在测试过程中发现,响应消息解析报错,后来做了调整。而请求能够正常解析,故没做调整。实际全新配置的,建议都参考响应结构定义。
<schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema">
<element name="ED_SRM_FORECAST_REQ">
<complexType>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.yankon.com/xi/SRM" targetNamespace="http://www.yankon.com/xi/SRM">
<xsd:element name="MT_SRM_RESP" type="DT_SRM_RESP" />
<xsd:complexType name="DT_SRM_RESP">
然后,PO中新建 请求ED,导入对应xsd文件
切换至Messages页签,可以检查确认请求报文结构。
同理创建 响应ED。
(5)定义 SI(Service Interface)
创建 请求SI
同理创建 响应SI
(6)定义 MM(Message Mapping)
创建 请求MM
同理创建 响应MM
(7)定义 OM(Operation Mapping)
创建 OM
保存所有对象,激活所有对象,ESR配置完毕。
2.2、PO端IB配置
返回PO主界面,点击 Integration Builder,进入Java版IB配置客户端
(1)在 BS_ERP_300 中,定义消息发送通道(Sender),配置如下,
(2)创建SRM端 BC(仅首次需要)
在 BC_SI 添加 服务接口 SI
(3)在 BC_SRM 中,定义消息接收通道(Receiver)
(4)创建 IC
配置如下:
保存,激活,查看WSDL
复制WSDL URL,发给外部系统调用,如SoapUI
2.3、PO端https证书导入
(1)证书的获取
浏览器打开相应地址,如下图
(2)证书的导入
重启PO系统即可。
3、SAP端代理服务创建
登录SAPGUI,执行事务码 Sproxy,进入对象导航界面,定位到前面创建的发送请求的SI,双击或右键→Generate,创建代理类
保存,激活即可,双击可以查看类源码
这里我们可以重点查看一下方法的参数结构,后面调用代理类的时候需要用到
4、SAP端请求服务
执行事务码 SE37,定义一个函数来封装代理类的调用,这里只做测试用,未定义入参出参。
FUNCTION ZFMMM_092.
*"----------------------------------------------------------------------
*"*"本地接口:
*"----------------------------------------------------------------------
DATA:LC_TEST TYPE REF TO ZPCO_SI_S4_SRM_FORECAST_REQ,
OUTPUT TYPE ZPED_SRM_FORECAST_REQ,
BODY TYPE ZPSI_S4_SRM_FORECAST_REQ_B_TAB,
LS_BODY TYPE ZPSI_S4_SRM_FORECAST_REQ_BODY,
FORECAST_LINES TYPE ZPSI_S4_SRM_FORECAST_REQ_F_TAB,
LS_FORECAST_LINES TYPE ZPSI_S4_SRM_FORECAST_REQ_FOREC,
FCST_LINE_DETAILS TYPE ZPSI_S4_SRM_FORECAST_REQ__TAB1,
LS_FCST_LINE_DETAILS TYPE ZPSI_S4_SRM_FORECAST_REQ_FCST,
INPUT TYPE ZPMT_SRM_RESP,
GS_EXCEPTION TYPE REF TO CX_AI_SYSTEM_FAULT, " 异常
GS_MSG TYPE STRING.
* &参数赋值
LS_FCST_LINE_DETAILS-FCST_DELIVERY_DATE = '2022-03-15'.
LS_FCST_LINE_DETAILS-FCST_QUANTITY = '30.0'.
LS_FCST_LINE_DETAILS-PURCHASER_REMARK = '采购方备注'.
APPEND ls_FCST_LINE_DETAILS TO FCST_LINE_DETAILS.
LS_FORECAST_LINES-FCST_LINE_TYPE = 'MONTH'.
LS_FORECAST_LINES-FCST_SEQ = '3'.
LS_FORECAST_LINES-FCST_DATE = 'month3'.
LS_FORECAST_LINES-FCST_QUANTITY = '30'.
LS_FORECAST_LINES-FCST_LINE_DETAILS = FCST_LINE_DETAILS.
APPEND LS_FORECAST_LINES TO FORECAST_LINES.
LS_BODY-ES_FCST_HEADER_ID = ''.
LS_BODY-ES_FCST_NUM = '2200001003361000001101421010'.
LS_BODY-LINE_NUM = '1'.
LS_BODY-SOURCE_CODE = 'SAP'.
LS_BODY-FCST_START_DATE = '2022-01-01'.
LS_BODY-ES_ITEM_CODE = '000000100000110142'.
LS_BODY-ES_SUPPLIER_CODE = '0000100336'.
LS_BODY-ES_CATEGORY_CODE = ''.
LS_BODY-ES_OU_CODE = '1000'.
LS_BODY-ES_UOM_CODE = 'PCS'.
LS_BODY-ES_AGENT_CODE = ''.
LS_BODY-ES_PURCHASE_ORG_CODE = ''.
LS_BODY-ES_INV_ORGANIZATION_CODE = '1010'.
LS_BODY-UPDATE_SELECTIVE_FLAG = '1'.
LS_BODY-FORECAST_LINES = FORECAST_LINES.
APPEND LS_BODY TO BODY.
OUTPUT-HEADER-APPLICATION_CODE = '服务方提供'.
OUTPUT-HEADER-APPLICATION_GROUP_CODE = '服务方提供'.
OUTPUT-HEADER-BATCH_COUNT = '1'.
OUTPUT-HEADER-BATCH_NUM = '202209014000000011'.
OUTPUT-HEADER-EXTERNAL_SYSTEM_CODE = '服务方提供'.
OUTPUT-HEADER-INTERFACE_CODE = '服务方提供'.
* OUTPUT-HEADER-PASSWORD = ''.
OUTPUT-HEADER-USER_NAME = '服务方提供'.
OUTPUT-BODY = BODY.
* &实例化
IF LC_TEST IS NOT BOUND.
CREATE OBJECT LC_TEST TYPE ZPCO_SI_S4_SRM_FORECAST_REQ.
ENDIF.
TRY.
CALL METHOD LC_TEST->SI_S4_SRM_FORECAST_REQ
EXPORTING
OUTPUT = OUTPUT
IMPORTING
INPUT = INPUT.
CATCH CX_AI_SYSTEM_FAULT INTO GS_EXCEPTION.
* &---异常信息获取
CALL METHOD GS_EXCEPTION->GET_TEXT
RECEIVING
RESULT = GS_MSG.
CATCH CX_AI_APPLICATION_FAULT .
ENDTRY.
CLEAR: OUTPUT.
COMMIT WORK.
ENDFUNCTION.
5、接口测试
(1)代理类执行,需要在与PO对应的测试环境进行测试,如开发300环境。
调整请求参数,或导入已经保存的请求变式
(2)函数执行
继续执行,看出返回信心 INPUT
原创文章,转载请注明来源-X档案
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)