文章目录
- 前言
- 一、案例介绍/笔者需求
- 二、WebService是什么?
- `a.`传输协议
- `b.`数据协议
- `c.`WSDL
- `d.`UDDI
- 三、WebService 和 WebApi 的区别以及优缺点
- `a.`主要区别
- `b.`优缺点
- 四、SAP如何发布一个webservice接口
- `a.`服务的激活
- `b.`函数的创建
- `c.`根据向导创建服务
- `d.`激活查看服务
- `e.`SOAMANAGER 配置Web服务 生成WSDL地址
- `f.`查看SOAMANAGER生成WSDL地址
- 五、WSDL接口文档详解
- `a.`WSDL 文件结构
- `b.`Documentation
- `c.`Policy
- `d.`Types
- `e.`Messages
- `f.`Port Types
- `g.`Bindings
- `h.`Services
- 六、Postman调用webservice接口
- `a.`请求URL
- `b.`请求方式
- `c.`请求头
- `d.`请求体
- `e.`调用查看返回结果
- `f.`权限配置
- 七、其他编程语言调用
- `a.`Python调用
- 八、总结
前言
本文2w字+,先 点赞 关注 收藏
制作不易 谢谢🤞
这篇文章给大家介绍一下SAP如何配置发布Webservice接口,也就是作为服务的提供者,发布之后并采用Postman和Python进行调用。这篇文件主要还是以SAP如何配置出Webservice为主来展开介绍,网上虽然也有类似的文章但是配图很模糊并且不完善知识也不连贯所以决定自己出一篇,虽然在现代以及往后的软件开发中,更偏向于使用WebAPI,但是webservice也有着不可替代的优势和应用场景。
一、案例介绍/笔者需求
这篇文章我们会在SAP中创建一个简单的函数,以这个函数创建企业服务为案例,也就是等同于把这个函数封装成 Webservice对象了,在这过程中我会首先介绍Webservice是什么?有什么优缺点?和 Webapi的主要区别是什么?后面也会介绍它生成的WSDL文件的详解。
二、WebService是什么?
Webservice 说简单点它就是一个接口,我们只要遵循它的数据格式和调用方式这个接口就能给我们返回相应的数据,然后我们再来看一下比较官方的描述:WebService是一种通过网络进行分布式计算和应用集成的技术。它允许不同的应用程序通过互联网进行互操作和通信,即使它们运行在不同的平台或编程语言上。WebService基于一系列标准协议,如SOAP(Simple Object Access Protocol)、WSDL(Web Services Description Language)和UDDI(Universal Description, Discovery, and Integration)。
a.
传输协议
Webservice 的传输协议通常使用HTTP或HTTPS作为传输协议,但也可以使用其他协议如SMTP(Simple Mail Transfer Protocol)和 JMS(Java Message Service)。
一般都是http、https,它两就是超文本传输协议只不过带s的是更安全,它们是Web通信的基础,定义了请求和响应的格式和规则,使得Web浏览器和服务器能够交换各类格式的信息。
b.
数据协议
Webservice 的数据协议是SOAP(Simple Object Access Protocol)是一种基于XML的消息协议,用于在Webservice之间交换信息。它定义了消息的格式和处理规则,支持复杂的数据类型和操作。这也就注定了Webservice必须使用XML格式的数据进行通信。
c.
WSDL
WSDL 可以理解为它是用XML编写的接口文档 ,注意是文档,用于描述Webservice的功能、操作、端点和访问方式。WSDL文件提供了服务的契约,详细描述了服务的接口和数据格式类型等等。
d.
UDDI
UDDI一个基于XML的标准,用于注册和发现Webservice。我自己的理解就是所有人配置发布的Webservice都会被记录在一个公共的注册表然后有人调用对应Webservice的时候就会去这个注册表中查找到对应的服务,找到了就可以调用没找到就调用失败。让我们在来看一下比较官方的解释:UDDI(Universal Description, Discovery, and Integration) 是一种基于XML的标准,用于注册和发现WebService。它类似于一个目录服务,帮助企业发布、查找和集成WebService。UDDI允许企业和应用程序通过互联网发布和查找WebService,从而实现更高效的业务集成和互操作性。
消费者可以根据服务的名称、分类、发布者等进行搜索。一旦找到匹配的服务,消费者可以获取服务的WSDL文档,从而了解如何访问和使用该服务。但是开发者一般直接使用WSDL文件解读和调用WebService,而不需要通过UDDI查找服务。WSDL提供了详细的接口描述,足以支持服务的发现和调用。所以这个UDDI了解一下就行了。
三、WebService 和 WebApi 的区别以及优缺点
a.
主要区别
1.传输协议
Webapi只能使用http而Webservice有多种可选但是一般也是http。
2.数据协议
Webservice只能使用XML的数据格式而Webapi是JSON或者XML都可以。
Webapi使用JSON格式,消息体小,传输效率高。
4.应用场景
Webservice适合端到端的场景提供服务,例如CS架构的客户端到服务器这种场景 或者是为了遗留系统需要与已有的SOAP服务进行集成。
Webapi更适合BS架构的应用场景就是浏览器到服务器这种,由于Webapi采用REST架构风格所以能被广泛支持几乎所有的现代编程语言和框架都原生支持RESTful API。
b.
优缺点
1.性能复杂度
这方面可以说Webapi完胜,由于Webservice有SOAP协议的存在需要处理SOAP消息,SOAP消息较复杂处理起来较为繁琐。而且使用XML,消息体较大,传输效率较低。
2.安全性
默认情况下Webapi是没有SOAP那样的内置安全机制,需要额外实现。
3.文档契约
Webapi如果接口有变化的话需要手动的更新文档容易出错,但是Webservice如果接口有变化那么只需要重新获取一下WSDL即可,所以学会看WSDL还是很重要的。
四、SAP如何发布一个webservice接口
SAP要配置发布Webservice接口主要有两个步骤,在GUI端根据向导创建生成一个企业服务,然后再使用事务码SOAMANAGER进入到浏览器SOAP的配置界面进行服务的创建配置,最终会生成获取WSDL文件的地址,有了这个WSDL之后我们就可以根据WSDL里面详细的接口描述来调用接口了。其实这些步骤就是将SAP已有功能封装成Webservice对象了,供其他系统调用,从而实现SAP与非SAP系统(如OA、PLM等)系统的集成。
a.
服务的激活
如果你们系统 域名访问、WDA程序相关的服务、SOAMANAGER相关的服务 都已激活能正常使用 可以跳过此步骤。 可以直接运行SOAMANAGER事务码看是否能正常进入配置界面如下图,如果可以就直接跳过此步骤。
1.域名解析
这个一般不会有问题的,你可以先忽略此步骤如果不行再回头来看,如果你们SAP是在内网本地进行部署的,现在你要是通过执行某些事务码例如webgui、soamanager、sap自己带出来的域名不能访问的话,那么你测试练习的时候可以先进行单机域名解析,注意是不能访问,不是访问报错,不能访问和访问报错是两码事。不能访问到就如同下图一样,这个url是我乱输入的。
1、 单机域名解析
我们能通过域名访问到指定的网站是因为DNS服务器或者是自己电脑把域名解析为了IP地址,我们要进行单机域名解析也就是让自己电脑解析此域名。下图是我们公司的一个填报考勤的网站,可以看到公司是没有购买域名的就是直接用ip访问的,那么如果我想用域名访问这个网站可以做如下操作。
路径为:C:\Windows\System32\drivers\etc
如下图所示可以看到能通过这个域名访问到了,这个就是单机域名解析的原理。如果你发现你把记事本中的解析删掉了,但是还能通过此域名访问,那是因为缓存的原因你需要清理一下浏览器缓存,如果是Edge浏览器你可以按 Ctrl +Shift + Del 只勾选 缓存的图像和文件 点 立即清除 即可。
如果你想要获取你们SAP系统的域名可以输入 webgui 这个事务码或者 soamanager 事务码 sap 都会打开浏览器把域名自己带出来。如下图所示就是webgui带出来的域名,图中关于服务的激活后面会有详细操作。
2、 集中域名解析
看完了单机域名解析其实这个集中域名解析也就好理解了。就是需要公司网管把解析条目添加到服务器所在网络的DNS服务中。这样处于这个网络的设备就都能通过域名访问了。
2.WDA服务
由于SOAMANAGER这个程序其实就是基于Netweaver的Web Dynpro程序,所以要使用SOAMANAGER就得激活WDA服务相关服务,SAP Netweaver组件安装后,默认是不激活 WDA 和 SOAMANAGER 相关服务的,是出于安全的考虑,我们需要通过事务码 SICF 逐个激活相关服务。
1、 进入定义服务界面 事务码:SICF 层次结构:SERVICE
2、 搜索服务名称:WEBDYNPRO 完整路径:/default_host/sap/bc/webdynpro
3、 搜索服务名称:MYSSOCNTL 完整路径:/default_host/sap/public/myssocntl
这个好像不激活也可以的 没激活就是暗的。
4、 搜索服务名称:WEBDYNPRO 完整路径:/default_host/sap/public/bc/webdynpro
5、 以下同上面一样先搜索再根据完整路径找到对应服务激活即可。
搜索 | 完整路径 |
---|---|
ur | /default_host/sap/public/bc/ur |
icons | /default_host/sap/public/bc/icons |
icons_rtl | /default_host/sap/public/bc/icons_rtl |
webicons | /default_host/sap/public/bc/webicons |
pictograms | /default_host/sap/public/bc/pictograms |
3.SOAMANAGER服务
SOAMANAGER 相关服务激活也同上面一样,需要注意的是在搜索的时候可能出现太多的节点不好找那么就根据完整路径自己手动找吧。
搜索 | 完整路径 |
---|---|
soap | /default_host/sap/bc/soap |
srt | /default_host/sap/bc/srt |
sap | /default_host/sap/bc/srt/rfc/sap |
sap | /default_host/sap/bc/webdynpro/sap |
appl_soap_management | /default_host/sap/bc/webdynpro/sap/appl_soap_management |
4.测试运行SOAMANAGER
完成以上操作之后可以尝试运行SOAMANAGER事务码,如果能顺利进入浏览器并且出现登录界面那么就证明服务都正常运行了。
如果出现如下界面点继续访问就行了。
如果页面返回的是403可能是某些服务没激活,一般访问的URL地址也就是服务激活对应的地址呢。下图的操作是通过URL获取WSDL文件的地址。可以看到没激活WSDL11服务就无法正常使用这个功能。
下图是输入事务码SOAMANAGER进入web配置界面,如果出现这些问题就要根据URL审查是不是哪些服务没有激活。有时候也不一定就是URL结尾的服务没激活。下图就是 /default_host/sap/bc/webdynpro 未激活而并非 appl_soap_management 未激活,所以出现问题还是要仔细审查一下这些服务的。
b.
函数的创建
我们就创建一个比较简单的函数,入参两个分别为 FIRSTNAME 和 LASTNAME 出参的话就一个把两入参拼接就是出参 FULLNAME 。
1.创建函数组
根据编号123456 操作即可。
2.创建函数模块
使用SE37或者直接在SE80下面的函数组创建即可,下图是SE80创建步骤,SE37创建的时候需要手动输入函数组名称。
3.函数配置
1、 设置为远程调用
2、 入参 出参
3、 代码逻辑
c.
根据向导创建服务
调出向导创建页面的方式有多种,可以从SE80包的层面创建,也可以从SE80函数模块层面创建,还可以从SE37进入对应函数创建。其中在SE80包层面创建的话可配置项是最多的。下面我将进行SE80包层面如何创建的详细步骤。
1.向导第一步
这一步是 选择要创建的代理的对象类型。 为什么叫代理对象呢?其实相对于我们这个RFC函数而言创建的Webservice就是代理服务,因为外部系统的请求进来之后首先是到了Webservice,然后Webservice再来调用我们的RFC。所以Webservice相当于我们RFC与外部系统之间的代理。其实SAP也提供了各类语言之间调用RFC的办法,但是相对于Webservice或者是走PI、PO、CPI 这些中间件通用性可配置性还是比较低的。这一步我们选择 服务提供者(Service Provider) 如下图所示。
这个步骤的这些选项允许我们在SAP系统中创建和管理不同类型的服务和相关对象,从而实现复杂的企业服务架构。根据我们的需求,选择相应的选项可以帮助我们更有效地定义和管理服务。如下表格是其他选项的简介。
选项 | 描述 | 用途 |
---|---|---|
Data Type | 定义数据的结构,包括字段、数据类型和长度。 | 用于描述消息或操作中的数据结构。 |
Message Type | 定义消息的结构。 | 用于描述在系统之间交换的数据格式。 |
Datatype Enhancement | 扩展现有数据类型。 | 允许增加额外的字段或属性到现有数据类型。 |
Fault Message | 定义如何使用外部Web服务。 | 用于在SAP系统中调用外部Web服务。 |
Service Consumer | 定义消息的结构。 | 用于描述在系统之间交换的数据格式。 |
RFC Consumer | 用于远程功能调用(RFC)的消费者定义。 | 允许SAP系统调用外部RFC服务。 |
Service Provider | 定义一个服务提供者。 | 用于将SAP系统中的功能发布为Web服务,供其他系统调用。 |
Event Provider | 定义事件提供者。 | 用于发布和处理事件,以便在系统之间进行异步通信。 |
Service Variant | 服务的不同版本或变体。 | 允许管理同一服务的多个版本。 |
Consumer Mapping | 定义服务消费者的映射。 | 用于将服务消费者映射到实际的服务实现。 |
Operation Mapping | 定义操作之间的映射。 | 用于将请求和响应消息映射到相应的操作。 |
Processing Type Domain | 处理类型的领域。 | 定义处理类型的分类。 |
Integration Scenario Definition | 定义集成场景。 | 用于描述如何在不同系统之间集成服务。 |
Semantic Contract | 定义语义合同。 | 用于描述服务之间的语义约定。 |
Contract | 定义合同。 | 用于描述服务提供者和消费者之间的合同。 |
Contract Implementation | 合同的实现。 | 定义如何实现合同中描述的服务。 |
Consumer Factory | 定义消费者工厂。 | 用于生成服务消费者实例。 |
Service Group | 定义服务组。 | 用于将相关的服务组织在一起进行管理。 |
2.向导第二步
我们选择如下图所示的选项。这个选项代表什么请看后面的表格。
选项 | 描述 | 用途 |
---|---|---|
Backend | 定义数据的结构,包括字段、数据类型和长度。 | 用于将SAP系统中的后端功能模块或BAPI暴露为Web服务。(具体我也不清楚) |
Enterprise Service Repository | 定义消息的结构。 | 用于通过企业服务库中的预定义服务来生成Web服务。 |
Existing ABAP Object (Inside Out) | 指现有的ABAP对象。 | 可以将函数组、函数模块、BAPI 暴露为Web服务。也可以说是封装成为web service对象了 |
External WSDL/Schema | 指外部的WSDL或XML Schema定义。 | 选择这个最终生成的webservice是会去调用外部的一个webservice等于是sap生成的webservice做了代理。 |
3.向导第三步
这一步是给我们创建的服务起一个名称再输入描述,这个名称会在后续的SOAMANAGER事务码中的配置web服务中用到。这个名称和函数名没啥关系哦,就是一个服务名称是另外的含义,后续管理查找配置服务会用到的。
4.向导第四步
根据需求我们选择 函数模块
5.向导第五步
选择要调用的函数,还有一个Map Name选项 一般用不上,Map Name的作用是在某些情况下,外部系统可能有特定的命名规范要求,你可以使用映射名称来符合这些要求,而不改变函数模块的实际名称,也有可能是为了起一个使外部调用者更容易理解服务名称,可以使用更具描述性的映射名称。
6.向导第六步
这一步是选择不同的安全配置文件(Profile)。每个Profile选项代表一种安全认证和传输保障的组合。由于我们是练习测试就选择无认证方式无传输保障的选项四了,其他选项的详情请看后面的表格。这个好像在SOAMANAGER还可以再次配置。
选项 | 认证方式 | 传输保障 | 描述 |
---|---|---|---|
Authentication with Certificates and Transport Guarantee | 使用证书进行认证。 | 提供传输保障(例如通过SSL/TLS)。 | 这种配置提供了高安全性,通过证书进行身份验证,并且确保数据在传输过程中是安全的。 |
Authentication with User and Password, No Transport Guarantee | 使用用户名和密码进行认证。 | 不提供传输保障。 | 这种配置提供了基本的身份验证,但数据在传输过程中没有加密或其他保障措施。 |
Authentication with User and Password and Transport Guarantee | 使用用户名和密码进行认证。 | 提供传输保障(例如通过SSL/TLS)。 | 这种配置结合了用户/密码认证和传输保障,提供了中等水平的安全性。 |
No Authentication and No Transport Guarantee | 不进行任何身份验证。 | 不提供传输保障。 | 这种配置没有任何安全措施,适用于不需要安全保障的非敏感数据。 |
7.向导第七步
这一步根据公司规定将这个服务存放到指定包和关联请求号,由于我是测试练习就放到本地包了。
8.向导第八步
最后一步点击完成 ,我们也可以看到这一步有提示说这个服务现在还没法使用,还需要在SOAMANAGER中配置。
d.
激活查看服务
1.激活服务
根据向导创建完之后需要我们激活服务,不然在SOAMANAGER里面是搜不到这个服务的。
2.测试运行服务
虽然我们这个服务还没在 SOAMANAGER 配置,外部系统还不能发现和调用,但我们可以在SAP本地测试的。
3.WSDL分页签查看
现在只要能访问SAP的网络的设备都可以通过如下图这个URL获取到这个WSDL文件,访问的时候如果要输入用户名和密码就输SAP登录的用户名密码就行。但是这个WSDL现在还不足以让外部系统来解读调用,你可以叫这个为 初始生成的WSDL 这个WSDL通常包含服务的基本结构和接口定义。它定义了服务的操作、消息类型、数据类型等内容。可以用于初步的服务调用和测试。也可以用下面这个链接获取,这个好像是用 WSDL11服务 专门获取WSDL的 URL。
http://<域名>:<端口号>/sap/bc/soap/wsdl11?services=< RFC >&sap-client=<客户端>
当你在SOAMANAGER中配置并激活Web服务后,系统会生成一个新的WSDL的 URL,这个WSDL除了包含初始WSDL的所有内容外,还会包含更多的配置信息,如实际的端点地址、安全设置、传输协议等。它是一个更完整、更详细的WSDL,反映了服务在实际运行环境中的配置。用于实际的服务调用和集成。它提供了客户端与服务端通信所需的所有详细信息,并确保服务按照在SOAMANAGER中配置的安全和传输设置运行。
4.其他分页签
其他分页签你们自己随便看看就行了感觉也没啥重要信息了。
e.
SOAMANAGER 配置Web服务 生成WSDL地址
这一步我们会在SOAMANAGER中配置并激活Web服务,系统会生成一个新的WSDL获取的URL,通过对这个WSDL的解读我们就可以准确调用这个接口了。
1.进入SOA管理界面
直接输入 SOAMANAGER 回车就行。进去之后点击 web服务配置
2.查找要配置的服务
进入之后如下图搜索我们要创建配置的服务。如果 SAP没有激活此服务或者在激活之前就打开了此页面是搜不到的。需要激活之后关闭此页面重新进入。
3.服务和绑定名称
这个新绑定名称是对服务的具体实现进行精细的配置和管理。我们每一个服务都可以配置出来多个接口的,比如Z_GLYN_JOIN_NAME这个服务可以配置两个接口,一个绑定的名称叫Z_GLYN_JOIN_NAME_HTTP再创建另外一个接口叫Z_GLYN_JOIN_NAME_HTTPS,代表这个服务有两个接口可以调用,只不过走的协议不一样,一个是HTTP另外一个是HTTPS,但是我们不仅仅可以配置协议 还有更多的信息可以配置。
3.安全配置
这一步是关于安全的配置。我先选无验证 后续再改验证方式看调用方式会有何变化。
3.SOAP协议
这块的配置没有什么特殊要求的话就保持默认吧。
3.完成配置
在我点击完成的时候报错提示 Property missing: AuthenticationMethod.ABAPServiceUser.Username 这个是因为安全配置那个步骤我忘记输入用户名和密码了。
f.
查看SOAMANAGER生成WSDL地址
根据上面配置完成之后我们就可以根据创建的服务获取WSDL了。
1.界面介绍
配置成功之后就会出现如下图所示,我出现了两个条目是因为我又新配置了一个为了演示那个新绑定名称的作用而已。
2.查看WSDL的URL
现在就可以通过如下图这个 URL 获取到WSDL了。有了这个WSDL就可以根据里面的信息进行接口的调用。但是前提你得能看懂WSDL所以下面我们会对WSDL的内容进行详解。
五、WSDL接口文档详解
WSDL文档看起来还是比较复杂的,一个 WSDL 文件包含多个重要部分,包括服务的端点、操作、消息类型等,笔者其实也是刚接触不久,我们只需要提取里面重要的信息就行了。后期我自己对WSDL文档摸清楚后会回来填坑,谢谢大家。首先我们要解读的WSDL文档如下。
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions targetNamespace="urn:sap-com:document:sap:rfc:functions"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsoap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:tns="urn:sap-com:document:sap:rfc:functions"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsdl:documentation>
<sidl:sidl
xmlns:sidl="http://www.sap.com/2007/03/sidl"/>
</wsdl:documentation>
<wsp:UsingPolicy wsdl:required="true"/>
<wsp:Policy wsu:Id="BN__Z_GLYN_JOIN_NAME">
<wsp:ExactlyOne>
<wsp:All>
<sapattahnd:Enabled
xmlns:sapattahnd="http://www.sap.com/710/features/attachment/">false
</sapattahnd:Enabled>
<saptrnbnd:OptimizedMimeSerialization
xmlns:saptrnbnd="http://schemas.xmlsoap.org/ws/2004/09/policy/optimizedmimeserialization" wsp:Optional="true"/>
<wsaw:UsingAddressing
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" wsp:Optional="true"/>
</wsp:All>
<wsp:All>
<sapattahnd:Enabled
xmlns:sapattahnd="http://www.sap.com/710/features/attachment/">false
</sapattahnd:Enabled>
<saptrnbnd:OptimizedXMLTransfer uri="http://xml.sap.com/2006/11/esi/esp/binxml"
xmlns:saptrnbnd="http://www.sap.com/webas/710/soap/features/transportbinding/" wsp:Optional="true"/>
<wsaw:UsingAddressing
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" wsp:Optional="true"/>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsp:Policy wsu:Id="BN__Z_GLYN_JOIN_NAME_soap12">
<wsp:ExactlyOne>
<wsp:All>
<sapattahnd:Enabled
xmlns:sapattahnd="http://www.sap.com/710/features/attachment/">false
</sapattahnd:Enabled>
<saptrnbnd:OptimizedMimeSerialization
xmlns:saptrnbnd="http://schemas.xmlsoap.org/ws/2004/09/policy/optimizedmimeserialization" wsp:Optional="true"/>
<wsaw:UsingAddressing
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" wsp:Optional="true"/>
</wsp:All>
<wsp:All>
<sapattahnd:Enabled
xmlns:sapattahnd="http://www.sap.com/710/features/attachment/">false
</sapattahnd:Enabled>
<saptrnbnd:OptimizedXMLTransfer uri="http://xml.sap.com/2006/11/esi/esp/binxml"
xmlns:saptrnbnd="http://www.sap.com/webas/710/soap/features/transportbinding/" wsp:Optional="true"/>
<wsaw:UsingAddressing
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" wsp:Optional="true"/>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsp:Policy wsu:Id="IF__Z_GLYN_JOIN_NAME">
<wsp:ExactlyOne>
<wsp:All>
<sapsession:Session
xmlns:sapsession="http://www.sap.com/webas/630/soap/features/session/">
<sapsession:enableSession>false</sapsession:enableSession>
</sapsession:Session>
<sapcentraladmin:CentralAdministration
xmlns:sapcentraladmin="http://www.sap.com/webas/700/soap/features/CentralAdministration/" wsp:Optional="true">
<sapcentraladmin:BusinessApplicationID>000C296C4B381EDC91F239BBC731D61C</sapcentraladmin:BusinessApplicationID>
</sapcentraladmin:CentralAdministration>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsp:Policy wsu:Id="OP__Z_GLYN_JOIN_NAME">
<wsp:ExactlyOne>
<wsp:All>
<saptrhnw05:required
xmlns:saptrhnw05="http://www.sap.com/NW05/soap/features/transaction/">no
</saptrhnw05:required>
<sapcomhnd:enableCommit
xmlns:sapcomhnd="http://www.sap.com/NW05/soap/features/commit/">false
</sapcomhnd:enableCommit>
<sapblock:enableBlocking
xmlns:sapblock="http://www.sap.com/NW05/soap/features/blocking/">true
</sapblock:enableBlocking>
<saprmnw05:enableWSRM
xmlns:saprmnw05="http://www.sap.com/NW05/soap/features/wsrm/">false
</saprmnw05:enableWSRM>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsdl:types>
<xsd:schema attributeFormDefault="qualified" targetNamespace="urn:sap-com:document:sap:rfc:functions">
<xsd:simpleType name="char10">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="10"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="Z_GLYN_JOIN_NAME">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="IV_FIRSTNAME" type="tns:char10" minOccurs="0"/>
<xsd:element name="IV_LASTNAME" type="tns:char10" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="Z_GLYN_JOIN_NAMEResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="EV_RESNAME" type="tns:char10"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
<wsdl:message name="Z_GLYN_JOIN_NAME">
<wsdl:part name="parameters" element="tns:Z_GLYN_JOIN_NAME"/>
</wsdl:message>
<wsdl:message name="Z_GLYN_JOIN_NAMEResponse">
<wsdl:part name="parameter" element="tns:Z_GLYN_JOIN_NAMEResponse"/>
</wsdl:message>
<wsdl:portType name="Z_GLYN_JOIN_NAME">
<wsdl:documentation>
<sapdoc:sapdoc
xmlns:sapdoc="urn:sap:esi:documentation">
<sapdoc:docitem docURL="http://mysap.goodsap.cn:50400/sap/bc/esdt/docu/sd_text?sap-client=400&sd_name=Z_GLYN_JOIN_NAME"/>
</sapdoc:sapdoc>
</wsdl:documentation>
<wsp:Policy>
<wsp:PolicyReference URI="#IF__Z_GLYN_JOIN_NAME"/>
</wsp:Policy>
<wsdl:operation name="Z_GLYN_JOIN_NAME">
<wsp:Policy>
<wsp:PolicyReference URI="#OP__Z_GLYN_JOIN_NAME"/>
</wsp:Policy>
<wsdl:input message="tns:Z_GLYN_JOIN_NAME"/>
<wsdl:output message="tns:Z_GLYN_JOIN_NAMEResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="Z_GLYN_JOIN_NAME" type="tns:Z_GLYN_JOIN_NAME">
<wsp:Policy>
<wsp:PolicyReference URI="#BN__Z_GLYN_JOIN_NAME"/>
</wsp:Policy>
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="Z_GLYN_JOIN_NAME">
<soap:operation soapAction="urn:sap-com:document:sap:rfc:functions:Z_GLYN_JOIN_NAME:Z_GLYN_JOIN_NAMERequest" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="Z_GLYN_JOIN_NAME_soap12" type="tns:Z_GLYN_JOIN_NAME">
<wsp:Policy>
<wsp:PolicyReference URI="#BN__Z_GLYN_JOIN_NAME_soap12"/>
</wsp:Policy>
<wsoap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="Z_GLYN_JOIN_NAME">
<wsoap12:operation soapAction="urn:sap-com:document:sap:rfc:functions:Z_GLYN_JOIN_NAME:Z_GLYN_JOIN_NAMERequest" style="document"/>
<wsdl:input>
<wsoap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsoap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Z_GLYN_JOIN_NAME">
<wsdl:port name="Z_GLYN_JOIN_NAME" binding="tns:Z_GLYN_JOIN_NAME">
<soap:address location="http://mysap.goodsap.cn:50400/sap/bc/srt/rfc/sap/z_glyn_join_name/400/z_glyn_join_name/z_glyn_join_name"/>
</wsdl:port>
<wsdl:port name="Z_GLYN_JOIN_NAME_soap12" binding="tns:Z_GLYN_JOIN_NAME_soap12">
<wsoap12:address location="http://mysap.goodsap.cn:50400/sap/bc/srt/rfc/sap/z_glyn_join_name/400/z_glyn_join_name/z_glyn_join_name"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
a.
WSDL 文件结构
这里重要的东西是 xmlns:tns=“urn:sap-com:document:sap:rfc:functions” 这个属性值会在我们制作请求体内容的时候用到,没有它会请求失败的。它在倒数第三行哦,具体来说它是命名空间后面会详细介绍命名空间的作用。
b.
Documentation
这个是个可选 元素,它意思你要是想获得更多关于这份WSDL文档的注释与描述应该去 http://www.sap.com/2007/03/sidl 网站 ,这个很好理解因为这文档其实就是SAP生成提供的。
c.
Policy
这里主要定义了策略的逻辑组合,策略(Policy)的逻辑组合用于定义 Web 服务的行为和特性,如安全性、事务性、消息传递可靠性等。策略的逻辑组合允许服务提供者和服务消费者明确和协商这些特性,以确保服务的正确和安全运行。
< wsp:ExactlyOne > 下面可以包含多个 < wsp:All > 表示策略中有多个选项,客户端和服务端必须选择其中一个。在我们的文档中 < wsp:ExactlyOne > 标签下面有两组策略组合因为有两个 < wsp:All > 标签。
< wsp:All > 表示策略中的所有选项都必须满足。你选择了组合一那么就得满足组合一的所有要求,选择组合二也是一样的。
d.
Types
这里定义了数据类型,和入参出参 以及参数的可选还是必输,但其实这里并不是真实定义出参入参的地方,这里你可以理解为只是定义还没使用,真正对入参出参起效果的是Messages,其实这些标签还有其他的属性后期遇到了再过来补充吧。
e.
Messages
这里才算定义了入参出参吧,它这样设计可能是为了复用吧。你看这里的定义就能跟上面哪些名称对应起来了吧。
f.
Port Types
根据上面的那些定义理解着看下图就行了。
g.
Bindings
Bindings 部分,用于将抽象的端口类型(portType)Z_GLYN_JOIN_NAME 绑定到具体的通信协议和消息格式。
h.
Services
Services 部分,用于定义具体服务的端口信息和通信地址。这里才是真正接口的调用地址。
六、Postman调用webservice接口
要正确调用一个接口必须遵循它的各种标准,首先我们要知道 请求URL、还有调用的方式是GET还是POST或者其他、还有请求头、请求体、权限设定,这些基本内容。
a.
请求URL
请求URL在WSDL中Services标签里面,具体就是 < soap:address location=“”/> 标签里面的location属性 http://mysap.goodsap.cn:50400/sap/bc/srt/rfc/sap/z_glyn_join_name/400/z_glyn_join_name/z_glyn_join_name
b.
请求方式
如果文档没有在 binding 部分明确指出的话一般就用 POST,因为HTTP协议的GET 方法不常用于 SOAP,它会将消息体包含在 URL 中,存在长度和安全性问题。如果有明确指出用GET的话就会如下图所示。
c.
请求头
请求头主要是设置 Content-Type 因为webservice通信消息格式是XML,所以要指明消息类型为XML,如果没有其他特殊需求的话一般设置一个Content-Type就行了。
d.
请求体
请求体设置还是有点东西的,这个玩意要你自己根据WSDL文档中信息推导出来。我先把我们这个接口请求体的内容放下面然后再慢慢解释。
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:sap-com:document:sap:rfc:functions">
<soapenv:Header/>
<soapenv:Body>
<urn:Z_GLYN_JOIN_NAME>
<IV_FIRSTNAME>托尼</IV_FIRSTNAME>
<IV_LASTNAME>斯塔克</IV_LASTNAME>
</urn:Z_GLYN_JOIN_NAME>
</soapenv:Body>
</soapenv:Envelope>
首先webservice的请求体有这么几个内容:
1、 Envelope:SOAP 请求体必须包含 Envelope 元素作为根元素。
上述的Envelope标签中有两个属性 xmlns:soapenv、xmlns:urn 前者是 SOAP 协议的命名空间用于定义 SOAP 消息结构中的标准元素,如 Envelope、Header 和 Body。 后者是 SAP 系统中的特定命名空间,用于定义与 SAP RFC 相关的元素和数据类型。urn 是命名空间的前缀,可以在 XML 文档中用于引用该命名空间中的元素。使用这些命名空间前缀可以明确区分不同来源的元素,确保 XML 文档的结构和内容被正确解析和处理。如果没有命名空间的指定 那么就无法获取WSDL准确的元素定义。所以这两个命名空间搬过来的时候一定要搬对。
2、 Header:SOAP 请求体可以包含可选的 Header 元素。
这里可以不用设置请求头内容。
3、 Body:SOAP 请求体必须包含 Body 元素,里面包含实际的消息。
Body里面的元素相对来说好理解一点,主要是这个 urn 命名空间要写对,要对应的上。urn是一个命名空间前缀,代表一个URI(统一资源标识符)命名空间。这种命名空间前缀用于区分和标识XML元素和属性,以避免命名冲突。 < urn:Z_GLYN_JOIN_NAME> 代表调用的具体方法或操作是 Z_GLYN_JOIN_NAME。
e.
调用查看返回结果
1、 设置 URL、调用方式、请求头。
2、 请求体与返回结果
f.
权限配置
上面接口调用的时候没有任何权限验证任何人都可以调用,现在我们修改服务配置来加上认证方式。
1.修改配置重新发版
记得重新发版一下。
2.效果演示
可以看到现在调用结果变了 提示权限问题。我将返回内容在浏览器解析之后画面如下。
3.设置授权
如下图设置授权。
七、其他编程语言调用
上面我们用POSTMAN调用成功了下面我们再用常用的编程语言调用试一下。
a.
Python调用
由于笔者对Python比较熟悉所以这里我也只用Python演示一下,其他语言的话也都大同小异,你们自己试试就行了。
1.效果演示
源码在下面。
2.Copy Code
pass
import requests
from requests.auth import HTTPBasicAuth
# 请求url
url = "http://mysap.goodsap.cn:50400/sap/bc/srt/rfc/sap/z_glyn_join_name/400/z_glyn_join_name/z_glyn_join_name"
# 设置请求头
headers = {
'Content-Type': 'text/xml;charset=UTF-8',
# 这个SOAPAction没试出来效果不加也没关系跟postman保持一致即可。
# 'SOAPAction': 'urn:sap-com:document:sap:rfc:functions:Z_GLYN_JOIN_NAME:Z_GLYN_JOIN_NAMERequest'
}
# 设置请求体
body = """
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:sap-com:document:sap:rfc:functions">
<soapenv:Header/>
<soapenv:Body>
<urn:Z_GLYN_JOIN_NAME>
<IV_FIRSTNAME>托尼</IV_FIRSTNAME>
<IV_LASTNAME>斯塔克</IV_LASTNAME>
</urn:Z_GLYN_JOIN_NAME>
</soapenv:Body>
</soapenv:Envelope>
"""
# 有权限验证这样调用
response = requests.post(url, data=body, headers=headers, auth=HTTPBasicAuth('uname', 'upwd'))
# 没权限校验这样调用
response = requests.post(url, data=body, headers=headers)
print(response.text)
八、总结
以上就是今天要讲的内容,本文仅仅简单介绍了SAP如何配置发布webservice并调用以及webservice的一些其他扩展内容,感觉笔者讲的好对自己有帮助的还麻烦点个免费的赞赞制作不易谢谢谢谢!!!如果有说错或者不好的地方还望大家提出来见谅。感觉笔者写的好的别忘了关注点赞加评论哦,也欢迎大家一起来讨论。谢谢!