本示例以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_typeString授权模式,固定值client_credentials
client_idString即对接账号(由服务方提供)
client_secretString客户端密钥(由服务方提供)
scopeString作用域,固定值default

⑤ 反馈示例
正确返回值

{
    "access_token": "97eb08ad-8c86-459f-9526-905caebe2958",
    "token_type": "Bearer",
    "expires_in": 2263,
    "scope": "default"
}

错误返回值

{
    "error": "invalid_grant",
    "error_description": "Bad credentials"
}

反馈参数说明

参数名称类型非空描述
access_tokenString访问令牌,用于业务接口调用。
token_typeStringToken类型
expires_inIntegeraccess_token的有效期,单位:秒
scopeString作用域

(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"
        }
    ]
}

请求参数说明

字段字段类型是否必填描述备注
applicationGroupCodeString应用组SRM提供,随着对接环境不同会变化
applicationCodeString应用SRM提供,随着对接环境不同会变化
batchCountString数据量对方系统提供,可不传
batchNumString批次号对方系统提供,不超过20位递增的数字,建议时间戳
externalSystemCodeString外部系统SRM提供,固定值
interfaceCodeString接口编码SRM提供,不同接口编码不同
userNameString用户名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"
        }
    ]
}

反馈参数说明

字段字段类型描述备注
batchNumString批次号请求的批次号
responseStatusString程序执行状态ERROR:失败,SUCCESS:成功;状态为ERROR说明整批数据程序执行异常,无需关心明细响应结构。状态为SUCCESS,需要从restResponseDtlDTOList中获取具体每条数据的执行状态
responseMessageString错误信息
executeResultString执行结果SUCCESS:数据全部执行成功,FAILED:数据全部执行失败,PART:数据部分成功部分失败

restResponseDtlDTOList

字段字段类型描述备注
documentIdLongerp业务单据唯一性标识暂无使用
documentCodeStringerp业务单据唯一性标识对应接口的唯一性字段
responseStatusString执行状态SUCCESS:成功,ERROR:失败(当前此笔单据执行的状态)
responseMessageString错误信息当前此笔单据执行产生的异常信息,如果状态为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档案

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐