笔者之前的文章 SAP ABAP Web Service 的创建与消费:保姆级教程发布之后,有朋友在评论区留言,询问 ABAP 除了 Web Service 之外,是否也支持 HTTP 呢?
ABAP 这么强大的语言,支持 HTTP 当然不在话下。网上有很多在 ABAP 系统基于 CL_HTTP_CLIENT 工具类,通过 HTTP 协议和第三方系统交互的代码例子。
本文介绍笔者项目中一个实际例子,实现的是在 ABAP 系统 A 通过 HTTP 调用 OData 服务,在 ABAP 系统 B 创建业务数据的需求。
这种需求实现的套路是:
弄清楚在 B 系统里通过浏览器创建业务数据的步骤
在 B 系统里使用 Chrome 开发者工具 Network 面板,记录 HTTP 交互明细
通过 Postman 向 B 系统发送 HTTP 请求
在 A 系统完成 ABAP 代码编写
下面我们按照这个套路来一步步实现。
1. 弄清楚在 B 系统里通过浏览器创建业务数据的步骤
我们选择一个简单的场景,在 SAP CRM Fiori 里创建 Opportunity,点击工具栏上的 + 号进行创建。
选择 Opportunity Type 之后,维护 Name,Account 等必填字段,点击 Save 按钮即可。
2. 在 B 系统里使用 Chrome 开发者工具 Network 面板,记录 HTTP 交互明细
我们只需要记录点击 Save 按钮之后,从浏览器端发送的 HTTP 请求的明细。
尽管 Network 里会出现多条 HTTP 请求的记录,我们只需要关注类型为 POST,且状态码为 201 的那一条记录。
状态码 201 Created 意思是成功创建了一条新的 Opportunity.
我们需要记录的数据有:
HTTP 请求完整的 url
请求头部字段的 Content-Type 值:application/json
请求头部字段 X-Csrf-Token
这些信息最终都将体现在我们编写的 ABAP 代码里。
最重要的是记录下这个 HTTP POST 请求的 Payload:
点击上图的 view source,可以看到 Payload 对应的 JSON 数据。直接拷贝下来,后续会粘贴到 ABAP 代码中。
3. 通过 Postman 向 B 系统发送 HTTP 请求
有了记录下来的步骤 2 的 HTTP 请求明细之后,我们就可以用 Postman 向系统 B 发送数据了。
步骤 2 里我们在 Chrome 开发者工具 Network 面板里观察到,HTTP 请求头部有个 X-Csrf-Token,需要维护一个合法的 CSRF Token.
这个 Token 需要我们显式向浏览器申请。
如何申请呢?我们再回到 Chrome 开发者工具。
在某个 HTTP 请求的头部字段里,发现了 X-Csrf-Token 值被填充为 Fetch,显然这个请求就是 Fiori 应用向后台服务器申请 Token:
果然服务器颁发的 Token,就包含在 Response Header 结构里,如下图所示:
现在我们就可以在 Postman 里分别进行两步操作。
第一步是通过 Postman 获取一个合法的 CSRF Token.
在 Postman 里新建一个 HTTP 请求,为其维护一个 HTTP 请求字段,命名为 x-csrf-token, 值设置为 Fetch.
HTTP 请求 Url 为:
https://{{host}}:{{port}}/sap/opu/odata/sap/CRM_OPPORTUNITY/?sap-client=001
这里的大括号连同里面的 host 和 port, 是 Postman 引入的变量语法,实际上起的是占位符的作用。
变量 host 和 port 的具体值,在 Postman 的 Environments 面板里维护。这样我们就不需要在 Postman 里去硬编码一些会反复使用到的值了。
点击 Send 按钮,收到 HTTP Status 200 OK 的状态码。服务器颁发的 CSRF Token 值,就存储在 HTTP Response Headers 字段里,如下图所示。
有了 Token 后,在 Postman 里新建一个 HTTP Post 请求,将前一步从服务器端申请到的 CSRF Token 的值,装填到 x-csrf-token 这个 HTTP header 字段中。
然后将 Accept 和 Content-Type 这两个 HTTP header 字段值设置为 application/json. 这一步是通知 ABAP 服务器,请使用 JSON 作为返回给我的数据格式。
然后在 Postman 请求的 Payload 里,将之前从 Chrome 开发者工具 Network 面板里观察到的 JSON 字符串拷贝过来。
Description 随便维护一个容易分辨的值,然后点击 Send.
一切正常的话,会收到 HTTP 201 Created 状态码,说明 Opportunity 创建成功。
在 Fiori UI 上根据 Postman 里装填的描述信息值,能够搜索到刚才用 Postman 成功创建的 Opportunity 数据。
4. 在 A 系统完成 ABAP 代码编写
至此只剩最后一步,即在系统 A 完成 ABAP 代码的编写。
基本思路就是,把前一个步骤即在 Postman 里的 HTTP 请求操作,逐个翻译成 ABAP 代码。
我把向服务器申请 CSRF Token,和调用 HTTP POST 请求进行创建操作这两个步骤,封装成了 zcl_odata_tool 工具类的两个方法。
然后在 ABAP 报表里,依次调用这两个方法。
create_opp 方法,返回的是 ABAP 系统 B 的 OData 服务,成功创建 Opportunity 之后返回的 JSON payload.
为了简单起见和节约时间,待创建的 Opportunity payload,除了 description 字段之外,其他数据都是在 create_opp 方法里进行硬编码的。
执行报表之前,将 zcl_odata_tool 类的四个属性的初始值,更改成自己 ABAP 系统的主机名,端口号,以及用户 credential 即可。
之前我的 SAP UI5 开发教程的配套代码,托管在 Github 上,有朋友反馈国内访问 Github 不太稳定,时好时坏,所以本文的源代码,我放在了百度网盘上:
https://pan.baidu.com/s/1b2IUGHfu6Zt60BrzydiQDw?pwd=4A9T
提取码:4A9T
大家动手使用我原创的这些代码,如果有疑问,欢迎评论区留言。