尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

SAP ECC如何将RFC函数封装为Web Service:发布与联调全流程指南

SAP ECC如何将RFC函数封装为Web Service:发布与联调全流程指南 这期聊聊 SAP ECC 对外发布 Web Service 的真实做法。做 SAP 集成的朋友都清楚ECC 自带那套 RFC、IDoc 虽然成熟但碰到电商平台、自研中台、移动端这种讲究通用性和跨语言接入的系统SOAP Web Service 反而是最省事的通道——我们直接用 ECC 的标准机制发布一个接口三方拿着 WSDL 就能调既不要求对方懂 SAP 技术栈也不用为每套外围系统单独开发适配器。这篇内容主要围绕“如何在 ECC 里把 RFC 函数封装成 Web Service”展开从接口设计、服务生成、SOAMANAGER 发布、WSDL 获取再到第三方实际调用和常见坑尽量把完整链路写清楚。适合刚接手 SAP 集成项目、需要独立发布接口的顾问也适合给外部系统开发人员做接口联调参考。先说个判断SAP ECC 发布 Web Service 这件事本质上不是“开发”问题而是“配置 封装”问题。核心代码量往往很小大头全在接口设计边界、服务发布路径、权限和网络策略上。只要把这几个环节理顺一套接口 3 小时内跑通是很常见的。1. 先想清楚什么时候值得发布 Web Service1.1 三种最具代表性的接入场景SAP ECC 的对外接口需求回头看项目里的案例基本集中在三类场景。第一类是主数据分发物料、客户、供应商这些基础数据要从 SAP 同步到外围系统。比如你上了个 CRM 或者电商中台不可能让用户在两套系统里分别维护物料档案最常见的设计就是 SAP 做主数据源头通过 Web Service 把新增和变更推送过去。第二类是业务单据创建外围系统需要替用户在 SAP 里下单、建档。典型的像供应商门户提交采购申请、门店 POS 上传销售小票、物流系统回传收货数据。这种情况通常不要求外部系统直接写 SAP 数据表而是封装成“输入业务数据 → SAP 执行 BAPI 校验 → 返回凭证号”的接口。第三类是查询类服务让外部系统实时查询 SAP 的库存、订单状态、价格等。这类接口逻辑简单但并发和性能要求通常比前两类更敏感要特别注意函数模块内部不要写大循环、不要每次都全表扫。判断要不要走 Web Service可以把它类比成“你给小区物业开了个访客窗口”RFC 类似直接给钥匙IDoc 类似投递信件而 Web Service 更像一个标准化的办事窗口谁都能按表格格式来提交材料。如果接的是自己团队控制的内部系统RFC 或 IDoc 是高效选择如果是异构团队、异构语言还要跨网络边界Web Service 是最不挑客户端的方案。1.2 备选方案不只 Web Service很多人一上来就在 SE80 里创建 Web Service其实发布之前应该先把链路都过一遍。ECC 对外集成的常用方式主要有四类方式适用情况主要代价RFC/BAPI 直连对方能用 SAP 连接库系统边界可控客户端耦合强升级易受影响IDoc 异步消息大批量、允许异步、可差错重推管理成本高调试链长Web ServiceSOAP异构系统、跨平台、实时同步需要封装性能一般中间件/API 网关已有 SAP PI/PO 或第三方集成平台多一层架构前期投资大我遇到过不止一个项目明明两边都是 Java却为了“统一走 API”硬上了 PI 的消息映射最后光是处理队列积压就花了一周。反过来也有需求明明只要查个库存却被要求开发 RFC 然后每家银行客户端都要装 SAP NetWeaver 库折腾半天不如直接给个 WSDL 实在。我的习惯是实时性 5 秒、对方是异构系统、无现成 ESB 强制要求这三个条件同时满足就优先发布 Web Service。2. 动手前置接口设计与测试物料2.1 接口设计函数模块封装是灵魂发布 Web Service 之前第一个关键决策是把什么暴露出去最忌讳的做法是直接把 SAP 的 BAPI 函数挂出去公开调用。原因很现实BAPI 的参数结构通常是深度嵌套的里面一堆 BAPI_RETURN、EXTENSIONIN、TABLES 结构外部开发人员看 WSDL 会直接崩溃联调成本极高。标准的做法是写一层薄封装函数模块把口径收敛成扁平化、业务化、稳定的输入输出。比如我们要做一个“客户主数据同步”接口封装函数可以长这样FUNCTION ZCRM_CUSTOMER_SYNC. *------------------------------------------------------------------ * 输入: * IV_ACTION TYPE CHAR1 C 创建 / U 更新 * IV_CUSTNUM TYPE KUNNR * IV_CUSTNAME TYPE NAME1 * IV_CITY TYPE ORT01 * IV_DISTRICT TYPE ORT02 * IV_PHONE TYPE TELNR * IV_CUSTTYPE TYPE KTOKD * 输出: * EV_SUCCESS TYPE FLAG * EV_MSG TYPE CHAR200 *------------------------------------------------------------------为什么用这种虚似结构而不用 BAPI 原始结构三个理由降低联调门槛第三方只要照着几个字段填值不会因为漏了哪个内表头而报错隔离系统变化SAP 里客户主数据表 KNVV、KNA1 字段再迭代封装函数内部消化掉WSDL 契约保持稳定方便加业务校验创建客户前要做税号校验、信用段检查这些逻辑放在封装函数里天经地义不会散落到外围系统。字段名最好一眼能看出含义长度、类型尽量和屏幕字段一致避免第三方对着报文猜语义。接口文档里建议写清楚枚举值、必填项、更新模式是覆盖还是部分更新这些细节后期联调时能少一半扯皮。2.2 用 LSMW 快速造好底层主数据接口联调最容易被低估的是测试物料准备。你不可能在正式库里随便创建几千个客户也不可能等业务手工录主数据。这时候 S_ECC 经典的 LSMWLegacy System Migration Workbench就是救命工具事务代码 LSMW。这里不谈 LSMW 的标准三步法读文件、映射字段、转换规则只说怎么用它服务 Web Service 联调批次里录入一批测试客户档案项目名称用 ZTEST 开头便于识别用“抬头数据 科目组”的批输方式比直接写 BDC 更稳遇到校验错误能在批输入会话里一目了然跑完以后用 SE16N 查 KNA1、KNB1确认客户号段不是 20000 开头的冲突号把 LSMW 记录另存为训练数据后面回归测试时重新跑一遍就行。LSMW 的精髓在于“把数据准备也变成可重复的过程”。有它在你今天创建一个接口下午就能拿到几十个真实结构、真实字段长度的测试主数据而不是手工一条条 01 事务代码敲进去。配合 Web Service 联调时输入什么客户号直接就有一条现成的 KNA1 记录等着效率完全不一样。2.3 准备 SOAP 测试工具真正的联调不是“在 SE80 里按 F8 看返回”而是让外部系统的报文真正打进来。所以下一步在电脑上准备至少两个工具SoapUI开源版就行最常用。导入 WSDL 以后能自动生成请求模板改字段、发请求、看响应都在一个界面上完成Postman如果你只想快速打一发 SOAP 报文Postman 也支持但要手动填 Headers适合做简单连通性验证浏览器 WSDL 直接访问只用来确认服务发布状态不适合当测试工具。SoapUI 里记得配置请求头加SOAPAction用服务定义里生成的通常是方法名认证方式选 Basic Auth输入 SAP 用户名密码勾上 “Show Raw Response”方便看完整的 SOAP 响应结构。有了这三样——封装函数、LSMW 造好的主数据、SoapUI你就可以进入正式的发布环节了。3. 现场实操从函数到可调用服务3.1 第一步编写函数模块并确认远程属性打开 SE80或者直接 SE37 进入函数构建器。这里最关键的一步很多人会漏函数模块必须勾选“远程启用的模块”Remote-Enabled Module否则后续生成 Web Service 时根本找不到它。实操路径SE37 输入函数名ZCRM_CUSTOMER_SYNC点击创建属性页签里把处理类型改成“远程启用的模块”导入、导出参数按设计定义好注意全部用平铺字段源代码里写校验逻辑调用 BAPI 前记得CALL FUNCTION BAPI_CUSTOMER_CREATE...这类标准 BAPI 并处理 RETURN。写校验代码时有个小技巧把错误信息统一拼到EV_MSG字段返回而不是让异常抛出去。这样第三方看到的永远是“业务上能看懂的字符串”不是 SAP 那些 SSTNR 异常类。比如客户税号非法就返回EV_SUCCESS E、EV_MSG 税号格式不正确请检查后重试。这个统一返回结构后面会直接影响 WSDL 里的输出字段设计等于把整个接口的“用户使用说明书”做进了报文里。函数写完后先用 SE37 直接 F8 跑一遍输入参数、校验、BAPI 调用都验证通过再进入下一步。千万别跳过这一步——很多发布后报错根因其实就是函数模块内部逻辑还没跑通。3.2 第二步生成 Web Service 定义接下来把函数模块变成 SAP 可发布的 Web Service 定义。主流做法有两种取决于你的 ECC 版本和团队习惯方式 ASE80 / 函数组向导生成SE80 里定位到函数模块所属的函数组右键函数模块选择“创建 → Web Service”系统会打开一个向导填服务名称、命名空间前缀选好导入导出参数在 SOAP 里映射的节点。方式 BSOAMANAGER 里生成浏览器打开/sap/bc/webdynpro/sap/appl_soap_management进入 SOAMANAGER找到 “Web Service 配置” 或 “Service Definitions”不同版本的叫法有差异选择“创建”模式选“基于函数模块”填 A 里创建的服务定义名称之后系统自动产生逻辑端口和后端绑定信息。这里要特别说明命名空间设计。SAP 生成 Web Service 时会让填 namespace不要随手填一个默认值。我习惯用统一格式http://yourdomain.com/sap/customer/sync命名空间相当于报文的“身份证”第三方会用它来解析 XML 节点。以后如果换服务名但想沿用同一个 WSDL 契约就是保持命名空间不变这种细节在接口版本升级时会非常值钱。服务定义生成后SOAMANAGER 会自动分配一个 endpoint 路径。老项目里常见的路径格式是/sap/bc/srt/wsdl/srvc_001/wsdl11/ws_policy但真正给第三方用的不是这个路径而是下面的调用地址。3.3 第三步发布、激活并完成结构权限发布环节有一个经常卡的配置点SICF 服务激活。SAP 所有 HTTP 服务都挂在 SICF 节点树上Web Service 对应的事务节点如果处于停用状态外部请求一来就是 404 或 HTTP 403。实操路径事务代码 SICF展开到/default_host/sap/bc/srt下的对应节点右键选择“激活服务”激活后到 SOAMANAGER 的“服务配置”里确认状态是“已发布”。之后还要在 SOAMANAGER 里做“认证配置”。最省事的是给服务配置一个指定的认证方式Basic Authentication。也就是第三方每次调用时在 HTTP Header 里带用户名密码SAP 帮你校验。这一步不做你会发现 SoapUI 打开 WSDL 正常但一发请求就返回Authentication failed。顺带提一个新手最容易忽略的点SOAMANAGER 里的“安全性”配置应该选择“仅传输级安全性”如果选到“消息级安全性”WSDL 会多出一堆 WS-Security 头第三方的代码实现难度直线上升。除非安全要求强制否则别自找麻烦。到这里一个 Web Service 已经发布成功。你可以自己先访问一下 WSDL 地址能打开 XML 文档就说明服务定义已经通了。4. 给三方用的接口手册4.1 拿到 WSDL 并定位端口服务发布后最关键的是把正确的 WSDL 地址给第三方。我不止一次遇到对方说“WSDL 打不开”最后发现是给了 SOAMANAGER 管理页面的地址而不是 WSDL 的 URL。真实可用的 WSDL 地址一般在 SOAMANAGER 里服务的“服务概览 / WSDL”页签可见基本格式如下http://ECC主机:端口/sap/bc/srt/wsdl/srvc_001/sap/bc/srt/wsdl/flv_ws_policy不同的 NetWeaver 版本格式略有差异最稳妥的获取方式是在 SOAMANAGER 里选择“查看 WSDL”浏览器里显示的地址就是真实 WSDL复制前检查一下主机名是否被解析成内网 IP如果外部系统访问不到就需要替换成公网域名或映射后的地址。外部系统拿到 WSDL 后第一步不是写代码而是用它生成客户端代理类。Java 用wsimportC# 用“添加服务引用”Python 用zeep。生成成功代表 WSDL 结构是合法的你发布的接口契约是完整的。4.2 SOAP 报文示例与基本调用逻辑为了让第三方少走弯路接口文档里最好给一份完整的 SOAP 请求示例。拿我们上面那个客户同步接口举例大致请求结构是这样soapenv:Envelope xmlns:soapenvhttp://schemas.xmlsoap.org/soap/envelope/ xmlns:cushttp://yourdomain.com/sap/customer/sync soapenv:Header/ soapenv:Body cus:ZCRM_CUSTOMER_SYNC IV_ACTIONC/IV_ACTION IV_CUSTNUM0000001234/IV_CUSTNUM IV_CUSTNAME测试客户有限公司/IV_CUSTNAME IV_CITY上海市/IV_CITY IV_DISTRICT浦东新区/IV_DISTRICT IV_PHONE021-58888888/IV_PHONE IV_CUSTTYPEZ001/IV_CUSTTYPE /cus:ZCRM_CUSTOMER_SYNC /soapenv:Body /soapenv:Envelope需要注意SOAP 的字段名大小写、命名空间前缀在 WSDL 里已经固定第三方最好在 SoapUI 里调试成功后再把这套报文语句抄到代码里而不是手工对着文档去拼 XML手工拼十有八九会漏掉命名空间声明。接口返回的报文也很重要。SAP 会把函数模块的导出参数映射到响应节点里外部系统只需要解析EV_SUCCESS和EV_MSG两个字段就能判断成败。这种“一个成功标志 一条文本消息”的返回设计对任何语言都是最容易解析的。4.3 认证凭据与传输安全第三方每次调用 Web ServiceHTTP Header 里要带授权信息。Basic Auth 方式下用户名密码用 Base64 编码放入 Authorization 头即可Authorization: Basic Base64(username:password)用户名密码不要做到代码里写死建议通过环境变量或配置中心管理。接口被调用的账号建立时只分配这个函数模块对应的角色最小权限原则。我就是在一个项目里吃过亏给了对方一个 SAP_ALL 的账号结果对方一测函数就顺手把一大堆配置表改了排查了一下午。传输安全方面如果 SAP 系统暴露在非完全可信网络务必上 HTTPS。ECC 标配的 HTTPS 是在 ICM 层做 SSL 终止具体在 SMICM 里看 HTTP 处理器配置或者借助前置 Web 服务器做反向代理。总而言之不要裸奔 HTTP 穿梭公网Basic Auth 的用户密码虽然是 Base64 编码但这只是编码不是加密抓包能直接看到明文。5. 上线后避坑记录5.1 常见报错排查速查实际联调过程中我归纳了一套问题定位顺序。按“网络 → 认证 → 参数 → 逻辑”四层排查90% 的报错能快速收敛。现象可能原因处理方式WSDL 打不开服务定义未激活 / 请求内网地址不通SICF 激活服务换用互通域名HTTP 401Basic Auth 错误 / 账号权限不足检查账号密码核对角色HTTP 405请求方法不对SOAP 只能用 POST检查客户端请求方法SOAP Faultfunction not found服务名或 namespace 不一致核对 SOAMANAGER 里的服务标识SAP 返回成功但数据未创建函数内部逻辑异常RETURN 没解析用 SE37 单独调试函数模块性能慢函数内部多表查询 / 无授权检查检查数据库追踪优化查询如果你在外部系统一侧看到SOAP-ENV:SERVER之类笼统错误多半是 SAP 后端函数抛了未捕捉异常。这时候最有效的办法是把函数模块再单独跑一遍看 SE37 的调试堆栈比看外部日志强多了。5.2 两个典型实战问题复盘先讲一个命名空间不一致的事故。有次负责发布的同事图省事在服务器上的命名空间里填了urn:sap-com:document:sap:rfc:functions结果第三方照着 WSDL 生成完客户端调用总是报 “找不到操作”。排查半天发现是命名空间最后多了个/WSDL 里生成的节点实际上带有/但手工写的测试报文中漏掉了一个字符导致整个报文无法匹配。从此我定了个死规矩所有测试报文一律从 SoapUI 导入 WSDL 生成绝不手打 Header 和 Body。第二个是权限配置的坑。接口上线后偶尔出现调用失败而刚才还能通。后来追踪会话文件发现SAP 设置了“会话过期时间太短”外部系统长连接空闲超过阈值后被 ICM 断开程序重发却用了同一个连接。这不是代码问题也不是接口问题而是 SAP 侧连接保活的配置。顺手让网络组在后端负载均衡上加了 TCP keepalive问题彻底消失。这些问题的共同教训是接口联调时的“疑难杂症”一半出在 WSDL 契约没严格执行上另一半出在底层网络、会话、认证这类基础设施。如果开始就用 SoapUI 作为单一事实来源大部分字符级错误当天就能暴露根本轮不到上线后再查。收尾一点个人经验把 Web Service 发布到 ECC 这个过程做完三五个项目后你会总结出自己的固定套路。我现在的固定顺序就是先写封装函数 → SE37 全部跑通 → 生成服务定义 → SOAMANAGER 发布 → SICF 激活 → SoapUI 导入 WSDL 验证 → 输出接口文档。每一步都检查标准不跳过不因为熟练就偷懒。个人最大的体会是接口联调顺不顺利根本不取决于 SAP 配置有多熟悉而取决于你对“契约”的态度命名空间、大小写、字段类型、返回结构任何一个地方模糊了后面联调都可能是天坑。把这套流程固化下来每个新接口其实是重复劳动但每个新接口也真的能稳定按时交付。
返回列表