采用 SAP UI5 sap.ui.unified.FileUploader 控件,结合 Gateway 框架,实现本地文件上传到 ABAP 服务器,不是一件困难的事情。
但由于项目实施的客观条件限制,如果不使用 SAP UI5 和 SAP ABAP Gateway 这两个框架,又该如何实现呢?
这是最近一个朋友咨询我的问题。实际上我早在 2014 年就做过类似的事情。本文介绍不使用 SAP UI5 和 SAP ABAP Gateway 框架,纯手工进行前后端编程,来实现文件上传的需求步骤。
本文提供的源代码,前端 JavaScript 代码和 后端 ABAP 服务器的文件接收代码,由于没有使用任何应用层面的框架,因此能够在 SAP 任何基于 ABAP 技术栈的 On-Premises 产品里运行。
我们从前后端两层的实现来分别了解这个需求的实现细节。
前端实现
前端代码比较简单,只有 30 行代码。新建一个 HTML 文件,把这 30 行代码粘贴进去。
其设计思路概述成以下 7 点。需要完整源代码的朋友,请从这个链接获得。
(1) 定义一个原生的 form 元素,使用 enctype 字段指定该表单发送到服务器的编码格式为 multipart/form-data.
(2) 该表单的数据使用 HTTP POST 方法发送到服务器。
(3) 表单里包含了三个 input 控件,类型分别为 email, text 和 file. 本文介绍的本地文件上传功能,就是借助第 8 行类型为 file 的 input 控件来完成的。点击第 11 行用 a 标签实现的超链接后,绑定到 a 标签的 sendForm 函数触发,进行数据发送工作。
(4) 将 form 表单里全部数据通过 DOM API document.forms.namedItem 解析出来,放入变量 oData.
(5) 第 17 行语句演示了通过代码的方式,往待发送往服务器的表单数据里,再添加新内容的方法。
(6) 该行维护了表单数据发送到 ABAP 服务器的具体地址,其 SICF 路径为 /sap/crm/file_upload.
文件上传到 ABAP 服务器后,我们如何验证上传是否成功,内容是否正确呢?出于验证目的,我硬编码了一个销售订单 ID 55824.文件上传成功后,我在 SAP CRM 系统里,将上传的文件创建为该销售订单的一个附件。
(7) 调用原生 API XMLHttpRequest 的 send 方法,把表单数据传送到 ABAP 服务器。
打开这个 HTML 文件,如下图所示,点击超链接进行文件上传。
ABAP 后端实现
因为我们不借助任何后端框架,这意味着我们必须基于最底层的 HTTP 协议,自行解析出客户端发送过来的 multipart/form-data 格式的数据并进行处理。
首先在事物码 SICF 里,根据前端代码里的路径 sap/crm/file_upload, 新建一个同样路径的处理节点。
完整的后端代码同样能从这个链接获得,本文不全部贴出,只介绍要点。
通过前端 form 表单三个 input 控件维护的输入值,加上前端代码中自定义的表单数据,被浏览器随机生成的 FormBoundary 所分隔。提交表单的完整数据,能够在 Chrome 开发者工具 Network 标签页里观察到。
因此,我的思路就是,根据回车换行符定位到上图 ABAP 变量 LV_DATA 包含的 form-data 块,如果该块包含了 content-type:text/plain,就说明此块包含的是上传文件的实际内容,对其解析即可得到上传文件的实际内容。
这里不少新手朋友们常犯的错误是,因为在 ABAP 调试器里观察到的回车换行符显示为“##”,因此在代码里,这些朋友也直接用单井号或者双井号进行字符串匹配,这当然无法工作。
在 ABAP 里要进行和换行符以及回车换行符相关操作,需要使用 ABAP 工具类 CL_ABAP_CHAR_UTILITIES 定义的常量:CR_LF 和 NEWLINE:
解析出上传的文本文件内容后,调用 SAP CRM 附件创建 API,将该文件内容作为一个附件,添加到系统 ID 为 55824 的销售订单中去。
本例为了简化起见,只支持类型为文本(text/plain)的本地文件上传成销售订单(其 BOR 类型为 BUS20000115)的附件,故文件类型和 BOR 类型都进行了硬编码。
点击附件超链接,打开该文件内容,发现和本地文件完全一致,测试通过:
当然,本文描述的实际是一个重新造*的场景。大家在实际项目开发中,如果没有特殊原因,还是尽量采用 SAP 提供的现成框架和工具,来完成诸如文件上传这种比较基础和底层的工作,从而把精力放到业务逻辑的编写中去。
感谢阅读。
Jerry 的 ABAP 专题
Jerry的ABAP, Java和JavaScript乱炖
ABAP开发人员未来应该学些什么
Jerry 2017年的五一小长假:8种经典排序算法的ABAP实现
Jerry的ABAP原创技术文章合集
300行ABAP代码实现一个最简单的区块链原型
使用Java+SAP云平台+SAP Cloud Connector调用ABAP On-Premise系统里的函数
在SAP云平台的CloudFoundry环境下消费ABAP On-Premise OData服务
ABAP vs Java, 蛙泳 vs *泳
聊聊C语言和ABAP
动手使用ABAP Channel开发一些小工具,提升日常工作效率
我用ABAP做过的那些无聊的事情
不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧
使用Visual Studio Code编写和激活ABAP代码
你的ABAP程序给佛祖开过光么?来试试Jerry这个小技巧
在SAP云平台ABAP编程环境上编写第一段ABAP程序
SAP官方发布的ABAP编程规范
ABAP Code Inspector那些隐藏的功能,您都知道吗?
还在用ABAP进行SAP产品的二次开发?来了解下这种全新的二次开发理念吧
ABAP Netweaver体内的那些寄生式编程语言
从SAP社区上的一篇博客开始,聊聊SAP产品命名背后的那份情怀
云端的ABAP Restful服务开发
如何在SAP云平台ABAP编程环境里把CDS view暴露成OData服务
使用abapGit在ABAP On-Premises系统和SAP云平台ABAP环境之间进行代码传输
30分钟用Restful ABAP Programming模型开发一个支持增删改查的Fiori应用
Jerry带您了解Restful ABAP Programming模型系列之二:Action和Validation的实现
Jerry带您了解Restful ABAP Programming模型系列之三:云端ABAP应用调试
SAP云平台上的ABAP编程环境里如何消费第三方服务
ABAP开发者上云的时候到了 - 现在大家可以免费使用SAP云平台ABAP环境的试用版了
学而不思则罔 - SAP云平台ABAP编程环境的由来和适用场景
SAP云平台里的三叉戟应用
如何基于Restful ABAP Programming模型开发并部署一个支持增删改查的Fiori应用
SAP 2019 TechEd Key Note解读:云时代下SAP从业人员如何做二次开发?
有哪些ABAP关键字和语法,到了ABAP云环境上就没办法用了?
ABAP开发环境终于支持以驼峰命名法自动格式化ABAP变量名了
利用ABAP 740的新关键字REDUCE完成一个实际工作任务
一段让人瑟瑟发抖的ABAP代码
昨日万圣节ABAP怪兽级代码谜团,公布答案啦
介绍一种在ABAP内核态进行内表高效拷贝的方法
使用SAP Cloud Application Programming模型开发OData的一个实际例子
当ABAP遇见普罗米修斯
使用ABAP绘制可伸缩矢量图
ABAP开发环境语法高亮的那些事儿
SAP错误消息调试之七种武器:让所有的错误消息都能被定位
使用ABAP操作Excel的几种方法
SAP GUI里的收藏夹事务码管理工具
SAP GUI和Windows注册表
有了Debug权限就能干坏事?小心了,你的一举一动尽在系统监控中
ABAP CCDEF, CCIMP, CCMAC, CCAU, CMXXX这些东东是什么鬼
实现ABAP条件断点的三种方式
使用SAT跟踪监控从浏览器打开的SAP应用的性能和调用栈
一个13年ABAP老兵的建议:了解这些基础知识,对ABAP开发有百利而无一害
SAP ABAP Netweaver容器化, 不可能完成的任务吗?
SAP产品增强技术回顾
SAP API开发方法大全
浅谈Java和SAP ABAP的静态代理和动态代理,以及ABAP面向切面编程的尝试
SAP ABAP应用服务器的HTTP响应状态码(Status Code)
SAP ABAP里存在Java List这种集合工具类么?CL_OBJECT_COLLECTION了解一下
ABAP面试题系列:写一组会出现死锁(Deadlock)的ABAP程序
SAP ABAP Netweaver服务器的标准登录方式讲解
SAP ABAP关键字语法图和ABAP代码自动生成工具Code Composer
SAP ABAP SM50的另类用途 - ABAP工作进程对数据库表读取操作的检测
关于SAP ABAP字符变量和字符串变量字符个数的一个知识点,和一个血案
SAP ABAP一组关键字 IS BOUND, IS NOT INITIAL和IS ASSIGNED的用法辨析
SAP ABAP和Java里的弱引用(WeakReference)和软引用(SoftReference)
SAP AMDP介绍 - ABAP托管的HANA数据库过程
给你的ABAP对象打上标签(Tag)
历史上的今天:编程语言中null引用的十亿美元错误
ABAP Development Tool 代码模板和其他一些实用技巧汇总
SAP ABAP Development Tool 提高开发效率的十个小技巧
如何在 SAP BTP 平台 ABAP 编程环境里消费基于 SOAP 的 Web Service
ABAP 真的会过时吗?聊聊 ABAP 的过去,现在和未来
基于 abapGit 和 abaplint 的 ABAP 持续集成的一个例子