拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SAP调用Web Service全流程详解:从WSDL导入到ABAP代理实践

SAP调用Web Service全流程详解:从WSDL导入到ABAP代理实践

做SAP跟外围系统打交道这些年,绕不开的一个技术点就是Web Service。无论你是让SAP把数据发给第三方系统,还是让SAP去调别人的接口,底层无非都是SOAP、WSDL、HTTP这些老伙计在干活。但SAP里的Web Service调用流程牵扯到事务码多、配置入口分散,新手上手经常被SE80、SOAMANAGER、SM59、STRUST这一串名字搞晕。这篇文章把整个调用流程从发布端到消费端串一遍,每个环节的配置路径、参数含义、代码写法、踩坑点都讲清楚,适合刚接触SAP集成的ABAP开发、实施顾问,也适合需要跟SAP联调接口的外围系统开发。看完全流程,你至少能独立完成一次从WSDL导入到ABAP代码调用的闭环,遇到SSL证书、SOAP Fault这类经典报错也知道往哪个事务码里找原因。

1. 前置认知:SAP里的Web Service到底是怎么跑起来的

1.1 SAP调用Web Service的本质

在动手配置之前,先把底层原理理清楚。Web Service在SAP里本质上就是RPC over HTTP,SAP的ABAP程序把要调用的业务方法包装成一个SOAP请求,通过HTTP/HTTPS发到目标服务器,然后接收返回的SOAP响应。反过来,SAP也可以把自己内部的函数模块、类方法发布成Web Service,让外围系统来调。

这里有个很多人忽略的点:SAP的Web Service跟Java、.NET里直接用SDK发请求还不完全一样,SAP有一套基于NetWeaver的WS框架,底层走ICM(Internet Communication Manager)进程,通过SICF服务节点接收和转发HTTP请求。所以配置的时候经常要留意SICF服务是否激活,很多“能调通但报404”的问题其实就出在SICF节点没激活。

SAP里的Web Service分成两种角色:

  • 服务提供方(Provider):SAP发布接口给外部调。
  • 服务消费方(Consumer):SAP调用外部接口。

这两个角色对应的配置路径完全不同,最容易被搞混。你先想清楚这次项目里SAP是哪头,再决定看下面哪一章。

1.2 环境清单:版本与必要的事务码

我的演示环境是SAP S/4HANA 2020,用的是SAP GUI 810客户端,ABAP版本是7.5x。如果你的系统是ECC 6.0 EHP7或NetWeaver 7.4以上,流程基本一致,个别界面字段位置略有差异,不影响操作。

全流程涉及的核心事务码列成一张表,后面讲到具体环节还会再展开:

事务码作用使用场景
SE80对象导航器,创建和浏览Web Service、客户端代理发布服务、导入WSDL都用它
SOAMANAGERWeb Service统一配置台配置端点、认证、传输,查看WSDL
SM59配置RFC目的地(HTTP类型)客户端调用时指定连接目标
STRUST证书管理处理HTTPS的SSL证书信任
SICFHTTP服务节点管理检查服务是否激活
SPROXY企业管理器,查看代理类和消息类型排查代理生成问题

这里多说一句,很多人在搜索“sap cpi”“sap po”是把它当成SAP调用Web Service的另一种通道,这类中间件确实能省掉ABAP层面的很多活,但属于集成方案选型的问题,不是SAP原生的调用方式。我在第4章会专门对比直连调用、CPI、PO三种路线怎么选,你先带着这个概念往下看。

2. 把SAP的接口“亮”出去:服务端发布Web Service

2.1 用SE80把函数模块发布成Web Service

大部分时候SAP作为服务端发布接口,发布源可以是函数模块(Function Module),也可以是类方法。最常见的做法是函数模块,因为业务顾问已经很习惯把逻辑写进FM里。

操作步骤是这样的:

  1. 进入SE80,展开你要放置服务的包,在包名上右键,选择“创建企业服务(Create Enterprise Service)”下的“Web Service”,或者直接在对象列表里选“企业服务”。
  2. 系统弹出向导,选择“从函数模块创建服务”或“从类方法创建服务”,这里我们选函数模块。
  3. 输入函数模块名(比如Z_CRM_ORDER_QUERY),设定服务名(Service Name)和包名。
  4. 生成完成后,SE80里会出现一个新的服务定义节点,展开能看到分配的操作(Operation)和函数模块的参数映射。

关键点:函数模块的类型和参数规则。不是所有函数模块都能直接发布,最好使用RFC类型的函数模块,参数用Importing、Exporting、Tables,返回值尽量用结构或表类型。用过sap alv oo搜索帮助这类面向界面的场景的人都知道,界面逻辑跟后端服务参数完全是两回事,发布Web Service时绕开所有跟ALV、List、屏幕输出有关的参数,只保留纯数据结构。

生成服务后还差最后一步:必须为服务指定传输端点。在SE80里双击服务名,找到“分配端点(Assign Endpoint)”,常见的传输类型是HTTP或HTTPS,绑定到SICF服务节点。这步很容易被跳过,忘了绑定端点,后面SOAMANAGER里根本看不到可用的调用地址。

2.2 SOAMANAGER里的端点与认证配置

配置服务真正的主战场是SOAMANAGER。输入事务码进入后,默认是一个浏览器风格的管理界面,搜索你刚发布的服务名,点进服务详情。

在“发送方配置(Sender)”界面可以看到服务名、接口名、操作名,重点是“配置(Configuration)”区域:

  • 端点(Endpoint):这里显示的URL就是最终给第三方系统调用的地址,一般形如http://主机:端口/sap/bc/srt/wsdl/flv_10002...,复制给外围开发直接用。
  • 传输设置:绑定传输类型HTTP/HTTPS,指定SICF节点路径。
  • 认证设置:默认是“用户/密码(User ID/Password)”,也可以选X.509证书认证。

我在实际项目里强烈建议,只要链路允许,服务端认证就用用户名密码而不是匿名访问。有个很经典的坑:第三方接口联调时老报401,排查半天发现SOAMANAGER里认证方式配成了“匿名(Anonymous)”,但调用方又带了用户名密码,两边不一致,SAP直接拒绝。这里没有谁对谁错,就是配置没对齐。

另一个值得留意的选项是WS-Security。如果需要做WS-Security用户名令牌校验,要在“安全配置”里指定“签名”和“加密”,这通常会跟ESB、企业服务总线对接时才需要。一般点对点联调用最简单的Basic Auth就够了,不必一上来就把WS-Security堆上。

2.3 给外围系统看的WSDL从哪里拿

配置完成后,外围系统最关心的是WSDL地址。WSDL是Web Service的“说明书”,包含了所有操作、消息结构、绑定地址。

获取WSDL有两种方式:

  • 在SOAMANAGER服务详情里的“接口”页签,点击“WSDL”链接,浏览器会下载或显示一个XML文件。
  • 直接在浏览器输入典型URL:http://主机:端口/sap/bc/srt/wsdl?service=xxx,SAP会返回标准WSDL。

注意一个细节:WSDL分“抽象接口(Abstract Interface)”和“具体绑定(Concrete Binding)”,两者地址不同。第三方工具(比如Java的Axis、.NET的WCF)导入时,通常用具体绑定的WSDL才能拿到完整的SOAP端点地址。有些外围开发的同事图省事,一上来就拿抽象WSDL导入,结果生成的客户端代码没法直接调用,这类问题我后面在排障章节还会提。

3. 让SAP去“敲门”:消费端代理创建与调用

3.1 用SE80导入WSDL生成客户端代理

现在角色调转:SAP要去调用第三方的Web Service。第一步是拿到对方的WSDL,然后把这个“外部服务描述”导入SAP,生成一个ABAP能直接调用的代理类。

在SE80里:

  1. 在包上右键,选择“创建企业服务”下的“服务消费者(Service Consumer)”。
  2. 向导里选择“从WSDL”导入,填入WSDL的URL或本地文件路径。
  3. 输入代理类名前缀(比如ZCO_),SAP会自动生成类和对应的消息结构。
  4. 完成后,SE80对象列表里会出现一个带“WS”图标的对象,双击可以看到类名和操作方法。

这里对WSDL本身有两个要求容易踩坑。第一,WSDL必须能被SAP的这个系统直接访问。如果第三方WSDL在公网上且需要特殊网络出口,SAP服务器访问不到,就会导入失败。解决办法是先下载WSDL文件连同XSD附件,放到应用服务器本地目录再导入。第二,WSDL里最好不要有SAP不认识的扩展元素,有些.NET服务生成的WSDL带soap12绑定或自定义策略断言,SAP解析会报错。遇到这种直接把WSDL从WSDL 1.1改回SOAP 1.1规范的版本,通常就能过。

提示:导入WSDL的过程本质上是把XSD复杂类型映射成ABAP数据元素和表类型。第三方接口字段多、嵌套深的话,生成的ABAP结构可能超过系统默认的嵌套层数限制,导入报“发生内部错误”的情况我遇到过好几次,解决办法是让第三方把接口拆细,减少结构层级。

3.2 SM59配置HTTP目的地

代理类生成后,还要给调用配置网络出口,也就是“这个请求通过哪个HTTP连接发出去”。这个配置在SM59里做。

进入SM59,创建一个新的RFC目的地连接类型为“HTTP连接到外部服务器(G型)”。

设置要点:

  • 目标主机(Target Host):第三方服务器的域名或IP。
  • 服务号(Service No.):HTTP就填80,HTTPS就填443。
  • 路径前缀(Path Prefix):填WSDL里绑定地址的路径部分,比如/api/order/query。
  • 激活SSL:如果走HTTPS,勾选SSL,并选择SSL证书(匿名客户端证书除外)。
  • 登录与安全(Logon & Security):填用户名密码或基本认证信息,注意这里的用户名密码是外部系统要求的基本认证账号,不是SAP里的账号。

如果是HTTPS接口,证书处理是最容易卡人的环节。第三方给的证书是自签证书或非公共CA签发证书时,SAP默认不会信任,调用会报“SSL证书错误”。解决办法是用STRUST,把对方证书导入SAP的SSL客户端证书存储(SSL Client SSL Client Anonymous)里。

具体操作:

  1. 用浏览器打开对方的HTTPS接口地址,导出其证书链为CER文件。
  2. 进入STRUST,展开节点“SSL Client(Standard)”。
  3. 导入“信任的证书”,把CER文件加进去。

操作完了记得保存激活,同时在SM59目的地里要确保SSL证书选择的是“匿名客户端证书(Anonymous Client Certificate)”,这样SAP握手时才会带上证书。

3.3 ABAP代码调用的两种写法

配置好目的地后,写代码调用。这里给出两种方式:推荐用代理类,排障时可以用HTTP客户端的兜底方案。

先说代理类方式。以生成的代理类ZCO_ORDER_QUERY为例,代码大致是这样的:

DATA: lo_proxy TYPE REF TO zco_order_query, lo_fault TYPE REF TO cx_ai_system_fault, ls_input TYPE zst_order_query_req, ls_output TYPE zst_order_query_res, lv_text TYPE string. TRY. cl_proxy_access=>create_by_rfc_destination( EXPORTING proxy_name = 'ZCO_ORDER_QUERY' destination = 'HTTPDEST' IMPORTING proxy = lo_proxy ). ls_input-order_id = '20250101001'. CALL METHOD lo_proxy->query_order EXPORTING input = ls_input IMPORTING output = ls_output. CATCH cx_ai_system_fault INTO lo_fault. lv_text = lo_fault->get_text( ). MESSAGE lv_text TYPE 'E' DISPLAY LIKE 'E'. ENDTRY.

注意cl_proxy_access=>create_by_rfc_destination这个方法名在不同版本里可能略有不同,有些系统用create_by_destination。你生成代理类后,可以在SE80里双击代理类确认它的静态方法,或者直接用类浏览器看继承关系。用代理类的好处是字段结构类型在编译期就检查了,出入参一目了然,消息映射也由SAP帮你做好。

另一种写法是底层HTTP客户端,适合手动拼SOAP报文、排查接口问题:

DATA: lo_http_client TYPE REF TO if_http_client, lv_url TYPE string, lv_soap TYPE string. lv_soap = |<soapenv:Envelope ...>...</soapenv:Envelope>|. cl_http_client=>create_by_destination( EXPORTING destination = 'HTTPDEST' IMPORTING client = lo_http_client EXCEPTIONS OTHERS = 1 ). lo_http_client->request->set_content_type( 'text/xml; charset=utf-8' ). lo_http_client->request->set_cdata( lv_soap ). lo_http_client->send( ). lo_http_client->receive( ). DATA(lv_response) = lo_http_client->response->get_cdata( ).

这种底层方式虽然繁琐,但配合Wireshark或者直接打印请求、响应报文,能在最短时间定位是SAP发出的报文不对,还是对方返回的报文SAP解析不了。实测下来联调阶段非常有用,线上问题百分之八九十都是报文内容问题,不是网络问题。

4. 集成方案选型:直连调用、SAP CPI还是SAP PO

4.1 直连调用的适用与边界

直连调用就是上面第3章讲的ABAP代理类方式,适合点对点简单集成,接口数量少、双方系统都能稳定访问对方网络、不需要大量数据转换和复杂路由。

它的优点:无中间件成本,ABAP开发直接可控,调试方便。 它的缺点:每个接口都要导入WSDL、生成代理、配置目的地,接口一多维护成本上升;跨系统重试、消息审计、版本兼容都得自己写;如果SAP和外围系统网络隔离严格,还要开防火墙端口。

有个场景我特别不建议直连:一个订单创建拆成了同步查询、校验、创建、推送多个接口,而且每个接口由不同团队维护。这种接口链路复杂,在ABAP里写一大堆顺序调用和错误分支,维护起来非常痛苦,不如让中间件集中编排。

4.2 SAP CPI与PO作为中间枢纽

SAP CPI(Cloud Platform Integration)和SAP PO(Process Orchestration)是SAP的集成中间件,它们作为“枢纽”的角色,SAP直连中间件,中间件再对接外部系统,而不是SAP直接去调用外部接口。

拿sap cpi来说,它是云上租户化的集成套件,支持从ABAP侧直接发起HTTP调用到CPI接口,或者从CPI反向调SAP的RFC、OData。好处是让你用BPMN、Integration Flow的可视化方式编排接口,SAP侧只要提供一个RFC函数或者OData服务,复杂的转换放在CPI里做。

SAP PO则是在地版的企业服务总线,功能类似,适合部署在企业内部的传统集成。很多项目会纠结选CPI还是PO,我的判断标准很简单:新项目、允许上云的优先CPI,运维轻、扩展快;系统全在内网、数据敏感度极高、项目采购流程已锁定的,才考虑PO。

用中间件的代价是请求链路变长,端到端延迟增加,而且出问题时排查链路要从SAP→中间件→外围逐段拆。但从一周联调进度来看,中间件带来的调试便利性通常能抵消这部分成本,接口多了尤其明显。

4.3 选型小结与决策表

我整理一个选型对照表,你可以对着自己项目的情况判断:

维度直连调用SAP CPISAP PO
部署位置ABAP应用层云租户企业内部
接口数量少(几个到十几个)多多
网络隔离要求需SAP直连外部只需SAP连CPI只需SAP连PO
数据转换能力弱,靠ABAP手写强,映射工具丰富强
运维成本低中偏高
调试复杂度低中(看中间件日志)中

补充一句,有的项目同时用CPI和直连,不冲突。比如核心财务接口走CPI统一管理,临时联调的小接口直接在ABAP调用,只要能说清楚边界和负责人,两种方式共存完全没问题。

5. 调用过程中的异常与排障实录

5.1 高频报错速查表

几年项目下来,这套流程里的报错其实高度集中,80%的问题翻来覆去就是那几个原因。我把最常见的做成了速查表:

报错或现象常见原因排查入口与解决
HTTP 401 UnauthorizedSM59认证信息错,或对方服务要求TokenSM59检查账号密码;确认是否走OAuth2
HTTP 404 Not FoundSICF服务节点未激活,或路径前缀不对SICF激活/sap/bc/srt/...路径;核对SM59路径
SOAP Fault业务数据校验失败,或报文结构不匹配打印SOAP报文逐段比对WSDL结构
SSL证书不受信任证书未导入STRUSTSTRUST导入对方证书链
连接超时网络不通或对方响应慢ping/telnet测试端口;检查ICM参数
WSDL导入失败WSDL版本或扩展元素不兼容转为WSDL 1.1导入;降级SOAP版本
加载Web视图时出错:Could not register service workerSAP GUI或浏览器插件环境问题清理GUI缓存、更新浏览器内核控件

最后一个“加载web视图时出错: error: could not register service worker: invalidstatee”严格来说不是Web Service调用本身的问题,是SAP GUI这种嵌入浏览器控件加载Web界面时的环境类报错,但搜索这个词的人很多,往往是在SOAMANAGER这类网页管理界面里碰到的。遇到它先别怀疑网络,先看本地客户端版本、清理缓存、换个版本试试,实测能解决大部分情况。

5.2 实战复盘:一次第三方接口联调全记录

说一个我自己的案例。之前做一个供应链项目,SAP要调一个外部物流平台的运单查询接口,对方是Java开发的,走HTTPS。联调那周,问题一个接一个。

第一个问题是WSDL导入不了。对方WSDL文件500多行,看似正常,但SAP SE80导入时直接报语法错误。我把WSDL下载下来看了一下,发现里面绑定了soap12:binding,SAP 7.5默认不透传SOAP 1.2绑定(至少老版本存在这个识别难题),让对方导出时换成SOAP 1.1版本,导入顺利通过。

第二个问题是报SSL证书错误。对方给的HTTPS证书是内网根证书签发的,不是公共根。SAP客户端握手时找不到信任链。我在STRUST里把对方根证书导入后,SM59还是报错。最后仔细看才发现,SM59的“SSL激活”那里还要在证书下拉框里选“匿名客户端证书”,而不是“默认客户端证书”,两字之差,行为完全不同,选错就永远握手失败。

第三个问题是业务层面的SOAP Fault。接口联通了,但SAP发送的报文对方程序一直抛“缺少必填字段”。打印出实际SOAP报文,发现SAP字段命名是按WSDL的XSD元素生成的,个别下划线、大小写跟对方服务端校验要求不一致。这个纯靠双方开发一起对着报文逐行核对,最终敲定统一字段名规则,问题才落地。

这三次问题有个共同点:都不是SAP配置本身的问题,而是“两边对齐”的问题。SAP的报错信息其实已经把方向指出来了,关键是你要学会从报错反推是网络层、证书层还是报文层,一层层剥。我个人的排查习惯是:先看SM59本身能否连通(SM59里有个“连接测试”按钮可以直接测),连通了再看证书,最后再打印SOAP报文看内容。

6. 搜索热词随手串讲:那些“看上去有关”的问题

6.1 周边热词解析

这篇文章的标题下面挂了一堆热搜词,我挑几个容易让新手产生困惑的说说,它们确实跟SAP集成同属一个生态,但属于不同技术要点。

  • sap md07:MRP物料需求清单事务码。有人搜它是因为物料需求数据经常要推给上下游系统,而推送方式常走RFC或Web Service。如果你要做的正是把MD07的结果集通过Web Service送出去,注意MD07取数逻辑在ABAP端处理好,别把界面报表的参数原样映射到服务接口。
  • sap workflow:工作流。SAP工作流经常需要触发外部系统审批动作,触发方式之一就是在工作流规则里调用Web Service方法,或由外部系统反向调用SAP工作流接口。这类场景建议把触发逻辑封装成代理类方法,方便工作流流程定义直接绑定。
  • sap fico:财务模块。外部系统(比如费控、资金系统)向SAP同步凭证时,最稳的集成方式是RFC/BAPI,但一些较新的云系统反而只提供Web Service接口,这时SAP就要按本文的流程去调。一个注意点:财务凭证写入关联的事务太多,Web Service调用成功后一定要做事务性检查,别只把整体服务状态当成成功依据。
  • sap po注册的jndi有多个相同名字:这属于SAP PO中间件本身的问题,常见于部署多套协同应用时JNDI重名冲突。如果你是在调Web Service的过程中碰到的,去检查PO的JNDI绑定别名和协同应用的上下文,把同名的配置拆开或改名即可,不影响SAP侧调用逻辑。

这些词背后其实都指向同一个底层能力:SAP和外部世界通信的方式。Web Service只是其中一种,但只要你把RFC、BAPI、OData、SOAP这些概念在脑子里整理成一个“远程调用”大类,再去看具体事务码,思路就顺了。

6.2 几个能减少返工的实用经验

最后分享几个我在实践中沉淀下来的小习惯,不一定写进任何一门课程里,但能实打实减少返工。

第一个,联调开始时先把WSDL和XSD存档。项目周期一长,或者接口迭代一两次以后,对方改了什么字段根本没人记得清楚。把你的代理类生成时间、WSDL版本、对应接口文档版本写在代码注释或传输请求描述里,半年后回来看一眼就知道这套代理是对应哪个版本的接口。我就是靠这个习惯,在客户现场救过好几次急。

第二个,SM59目的地命名要有规律。我见过有人建了十几个HTTP目的地,叫HTTP1、HTTP2、TEST……三个月后谁也不敢动它们。我习惯用Z_HTTP_系统名_接口用途这种格式,比如Z_HTTP_LOGISTICS_ORDER,一看名字就知道是什么,排查问题时能少猜半天。

第三个,不要把超时参数设成默认值就完事。很多外部接口响应慢,SAP默认ICM超时是60秒,但对方业务逻辑复杂时可能超过这个时间。调用前跟对方确认95分位的响应时间,如果接近阈值,就在SM59或者ICM参数里调整相应的超时设置。这里的“接近阈值”指的是对方主流响应时间跟SAP的超时值相差不足10秒,因为网络抖动、重试都会进一步放大延迟,留足余量才不会频繁断链。

第四个,代理类的访问方式建议用cl_proxy_access=>create_by_rfc_destination,这个方式把代理类跟SM59目的地绑定,处理逻辑在选择屏幕上清晰可查,比直接把URL硬编码在代码里靠谱。哪怕你为了快速验证先用HTTP客户端拼报文,也至少留一个代理类的调用入口,后续维护会轻松很多。


我在实际项目里最终得出的体会是:SAP调用Web Service这件事,配置步骤就那么多,难度在于你不知道哪一步细节会让整个链路挂掉。证书选错一个下拉项、WSDL多一个SOAP版本标记、SM59路径漏写一段,每次都是让你怀疑人生的报错。但反过来想,这些问题全都有迹可循,只要养成分层排查的习惯——网络层、认证层、报文层、业务层一层层过,再多复杂的接口也能稳稳拿下来。希望这篇全流程详解能帮你少走几个弯路,把时间花在业务接口建设上,而不是跟证书和WSDL纠缠。

返回列表