一命速通 国服CPI部署全流程 二——CPI相关接口开发
第八步 CPI调用SAP RFC以及透传HTTP接口服务
https://blog.csdn.net/qq_41787379/article/details/134145374
参考上面大佬的操作,你可以很轻松的将一个rfc函数,包装成一个http接口让外围系统去调用。
以下示例为大家展示最小的开发量实现接口的代理
创建RFC函数的CPI代理
添加一个Integration Flow
输入名称,标识默认和名称一致 点击添加并在编辑器中打开
通常我们发布的接口都是restful协议,通过body中的负载将值传入RFC函数中,这里先点击右上角的编辑,进入编辑模式
然后点击连线
将sender和start连接
弹窗中我们选择https
点击https的线,可以打开下方的窗口。如果窗口太小,可以鼠标向上拉
点击connection,在address中,创建一个外部接口可以调用的地址,我们这里就叫他test吧
这里地址前需要打斜杠 因为接口调用的时候,post,get协议可能会影响到后面真正接口地址的协议,可以取消CSRF Protected的勾
官方默认body负载40MB,不建议超过它,可能会导致CPI内存不足 如果body负载是json字符串,这里需要将json转换成xml
选择start和end中间的线,点加号
选择转换器中的JSON到XML转换器
如果你打算将json中的字段转换成xml不同名称的字段,可以勾选Use Namespace Mapping,然后添加namespace的转换关系。这里我们默认json和xml名称一致,所以取消Use Namespace Mapping的勾选
转换后的xml需要一个根名称,系统默认是root,这里可以改成接口函数名+request的形式进行区分
转换xml之后,我们添加字段的mapping。选择线段点击加号。
选择映射中的消息映射
点击映射的图标,点击创建按钮
第一次的映射是传入到RFC函数中,所以这里需要在左侧添加XSD格式的文档,右侧添加函数的wsdl文件
现在是传入,所以我们要选上面的那一项,下面的是返回消息
现在直接拖动左侧的字段,连接右侧的字段就完成了字段的mapping
点击右上角确定,保存操作
接下来要添加接口的组件,在此之前,先调整下窗口,将Receiver拖动到下方,Integration Process窗口拉长,end往后调整
这次添加外部调用-请求回复
然后线段连接下面的Receiver
选择RFC 因为前面用到了WSDL,所以这里不需要考虑地址的问题,只需要在connection添加BTP平台上配置好的目标即可
接口调用结束,我们再加一次消息映射
这次左侧要添加RFC的WSDL中的返回部分,之前已经导入了wsdl文件,这里可以直接选择
直接字段拖动完成mapping
如果你需要返回json,这次还需要添加一个转换器
如图调整参数。如果xml结构中存在表,需要添加转换关系,具体教程见下文
到这里,接口基本创建完成。点击Integration Process窗口外的空白部分,唤出Integration Flow窗口,General可以填入接口的描述信息,方便后续查看管理; Error Configuration可以让接口的保存信息返回给调用者,否则你只能在CPI日志中查看错误消息
最后依次点击保存、另存为版本、部署,完成接口的发布
接口部署后可以在部署状态中跳转到地址页面。可以看到,接口地址是CPI的通用域名+http+自定义的地址。有点时候跳转过来,可能看不到地址,不着急,多刷新几次等待即可。
|
创建Restful接口的CPI代理 直接透传接口,操作就简单多了,参考上面的操作,直接进行外部调用-请求回复
拉线选择HTTP
如果是外网的接口,代理类型选择Internet,Address直接填写外网接口的地址即可,方法这里需要根据实际情况去选择。这里的地址支持HTTP和HTTPS两种协议。
但如果你调用的是通过SCC代理的内网的接口地址,只能支持HTTP协议。代理地址选择On-Premise,Location ID要根据连接的SCC系统输入对应的值。
关于接口的登录请求,无论内外网,SAP预设了一些登录方式
比如我们选择Basic认证,Credential Name填入预设的登录方式。配置见下文。
在监控的安全材料里面,我们进行认证信息的配置。部分外围系统可能无法通过预设的方式实现认证,请注意区别。
|
这里解释一些小坑
导出RFC函数WSDL地址
这里我开始还以为需要发布一个webservice来解决,后来发现并不需要。
首先打开事务代码sicf,激活/sap/bc/soap/wsdl11

我们测试服务,修改网址
https://xxxxxx:44300/sap/bc/soap/wsdl11?sap-client=100&services=ZSD_INT_001
services后面跟的函数名,必须大写
之后就能得到一个xml文件,另存为的时候修改扩展名为WSDL

外部系统的接口字段部分,我们要mapping的字段,是要手搓出来xsd文件的
这里一定程度上可以参考wsdl文件,但wsdl的参数信息太复杂了,我们不需要,这里精简一些,做一个教程
https://www.cnblogs.com/amylis_chen/p/9369686.html
<!--/* Font Definitions */@font-face{font-family:"Cambria Math";panose-1:2 4 5 3 5 4 6 3 2 4;mso-font-charset:0;mso-generic-font-family:roman;mso-font-pitch:variable;mso-font-signature:-536869121 1107305727 33554432 0 415 0;}@font-face{font-family:等线;panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-alt:DengXian;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:-1610612033 953122042 22 0 262159 0;}@font-face{font-family:楷体_GB2312;mso-font-alt:楷体;mso-font-charset:134;mso-generic-font-family:modern;mso-font-pitch:auto;mso-font-signature:0 0 16 0 262144 0;}@font-face{font-family:"\@等线";panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:-1610612033 953122042 22 0 262159 0;}@font-face{font-family:"\@楷体_GB2312";mso-font-charset:134;mso-generic-font-family:modern;mso-font-pitch:auto;mso-font-signature:0 0 16 0 262144 0;}/* Style Definitions */p.MsoNormal, li.MsoNormal, div.MsoNormal{mso-style-unhide:no;mso-style-qformat:yes;mso-style-parent:"";margin-top:0cm;margin-right:0cm;margin-bottom:8.0pt;margin-left:0cm;line-height:115%;mso-pagination:none;font-size:11.0pt;mso-bidi-font-size:12.0pt;font-family:等线;mso-ascii-font-family:等线;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:等线;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:等线;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:"Times New Roman";mso-bidi-theme-font:minor-bidi;mso-font-kerning:1.0pt;mso-ligatures:standardcontextual;}.MsoChpDefault{mso-style-type:export-only;mso-default-props:yes;font-family:等线;mso-bidi-font-family:"Times New Roman";mso-bidi-theme-font:minor-bidi;}.MsoPapDefault{mso-style-type:export-only;margin-bottom:8.0pt;line-height:115%;}/* Page Definitions */@page{mso-page-border-surround-header:no;mso-page-border-surround-footer:no;}@page WordSection1{size:612.0pt 792.0pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;mso-header-margin:36.0pt;mso-footer-margin:36.0pt;mso-paper-source:0;}div.WordSection1{page:WordSection1;}--><schemaattributeFormDefault="unqualified"elementFormDefault="qualified"xmlns="http://www.w3.org/2001/XMLSchema"><elementname="ZSD_INT_003_Request"><!-- 这里只表示是传入参数,不会实际影响结构 --><complexType><sequence><elementname="I_ADPNR" type="string"/> <!-- 一个字段 --><elementname="I_REQUEST" type="string"/><elementname="XLIKP"><!-- 一个结构 --><complexType><sequence><elementname="VBELN" type="string"/> <!-- 一个结构里的字段 --><elementname="NAME1" type="string"/><elementname="ERNAM" type="string"/></sequence></complexType></element><elementname="XLIPS" minOccurs="0"maxOccurs="unbounded"><!-- 一个表 只需要是数组就可以,不需要和RFC的WSDL完全一致 --><complexType><sequence><elementname="VBELN" type="string"/> <!-- 一个表行里的字段 --><elementname="ERNAM" type="string"/><elementname="POSNR" type="string"/></sequence></complexType></element></sequence></complexType></element></schema>
最后说一下http直接透传的接口。这部分接口大部分是直接透传json,不需要额外转xml,所以接口的制作会少几步转换,其他的大同小异
比如下图的例子

不管日志,这里可以直接调用接口地址。根据具体情况使用不同的Method。
这里说一些mapping过程中遇到的小坑:
传入参数中如果有表藏在其他结构里,mapping的时候,可能需要你这么拉线:

左侧的detail表和右侧的DETAIL表做关联,不能直接拉线到右侧item上,否则会没有值输出。这里需要将两个都关联上才可以。
如果你的表没有藏在其他结构里面,可能会简单一些,只需要将表连在右侧item上就可以。

实际开发中,我们也会遇到传入的数据格式和接收方的数据格式结构不是完全匹配的情况。特别是在接收方数据格式层级可能比传入数据的层级更多,有可能在mapping过后发现无法得到数据。
比如下方的例子,接收方(右侧)的MBS上面还有一个节点叫IS_DATA。这个时候,我们不能直接将左侧的mbs和右侧的MBS连接,还要将mbs和IS_DATA连接。不这么做会mapping出一个空结果。

上面针对传入参数的例子,可以总结出规律:如果数据结构node节点复杂,mapping的时候,最好将上层没有被关联过的节点也关联上,不然会导致数据传递失败。
传出参数中如果有表结构,mapping的时候,可能需要你这么拉线:

左侧DETAIL不做连线,将下面的item连接右侧的detail即可。
但是仅仅这么做,输出的JSON,detail不是一个表,而是多行的结构。所以我们还需要加点设置:

我们需要在这里注册下我们的表结构。
关于HTTP协议接口调用过程中的异常,如果对方系统会针对非200状态返回不同的有效body值,那么CPI自带的异常捕获功能要关闭,不然这部分消息无法被透传。

快上线了,CPI要往生产系统部署了,我选择最古朴的发布方式:导出到本地,然后导入到生产环境。这一招还是我在PO、PI时代学会的,主打一个好用。但是导出的时候,系统报错:

草稿?我都部署测试了好多次了,哪里来的草稿???

仔细一想,为了少写重复的脚本,我都是将接口复制后修改的。复制后自动生成版本1.0.0。之后再修改,就自动变成了Draft草稿了。坑爹的是,我都部署了,这个版本号不会自动生成,保持着这个状态。没办法,进入编辑一下,另存为版本,结束。


关于HTTP协议的透传规则:body和params的内容是可以直接透传的,但是Headers的内容需要指定,或者CPI中自己替换。

在允许的标头里配置你要透传的Headers,用竖线|进行分割。
或者添加内容修正符。


当然,HTTP这里也需要指定一下,多个Headers需要竖线|分割:


























































