javascript
不使用任何框架,手写纯 JavaScript 实现上传本地文件到 ABAP 服务器
這是 Jerry 2021 年的第 69 篇文章,也是汪子熙公眾號(hào)總共第 346 篇原創(chuàng)文章。
采用 SAP UI5 sap.ui.unified.FileUploader 控件,結(jié)合 Gateway 框架,實(shí)現(xiàn)本地文件上傳到 ABAP 服務(wù)器,不是一件困難的事情。
但由于項(xiàng)目實(shí)施的客觀條件限制,如果不使用 SAP UI5 和 SAP ABAP Gateway 這兩個(gè)框架,又該如何實(shí)現(xiàn)呢?
這是最近一個(gè)朋友咨詢我的問(wèn)題。實(shí)際上我早在 2014 年就做過(guò)類似的事情。本文介紹不使用 SAP UI5 和 SAP ABAP Gateway 框架,純手工進(jìn)行前后端編程,來(lái)實(shí)現(xiàn)文件上傳的需求步驟。
本文提供的源代碼,前端 JavaScript 代碼和 后端 ABAP 服務(wù)器的文件接收代碼,由于沒(méi)有使用任何應(yīng)用層面的框架,因此能夠在 SAP 任何基于 ABAP 技術(shù)棧的 On-Premises 產(chǎn)品里運(yùn)行。
我們從前后端兩層的實(shí)現(xiàn)來(lái)分別了解這個(gè)需求的實(shí)現(xiàn)細(xì)節(jié)。
前端實(shí)現(xiàn)
前端代碼比較簡(jiǎn)單,只有 30 行代碼。新建一個(gè) HTML 文件,把這 30 行代碼粘貼進(jìn)去。
其設(shè)計(jì)思路概述成以下 7 點(diǎn)。需要完整源代碼的朋友,請(qǐng)從這個(gè)鏈接獲得。
(1) 定義一個(gè)原生的 form 元素,使用 enctype 字段指定該表單發(fā)送到服務(wù)器的編碼格式為 multipart/form-data.
(2) 該表單的數(shù)據(jù)使用 HTTP POST 方法發(fā)送到服務(wù)器。
(3) 表單里包含了三個(gè) input 控件,類型分別為 email, text 和 file. 本文介紹的本地文件上傳功能,就是借助第 8 行類型為 file 的 input 控件來(lái)完成的。點(diǎn)擊第 11 行用 a 標(biāo)簽實(shí)現(xiàn)的超鏈接后,綁定到 a 標(biāo)簽的 sendForm 函數(shù)觸發(fā),進(jìn)行數(shù)據(jù)發(fā)送工作。
(4) 將 form 表單里全部數(shù)據(jù)通過(guò) DOM API document.forms.namedItem 解析出來(lái),放入變量 oData.
(5) 第 17 行語(yǔ)句演示了通過(guò)代碼的方式,往待發(fā)送往服務(wù)器的表單數(shù)據(jù)里,再添加新內(nèi)容的方法。
(6) 該行維護(hù)了表單數(shù)據(jù)發(fā)送到 ABAP 服務(wù)器的具體地址,其 SICF 路徑為 /sap/crm/file_upload.
文件上傳到 ABAP 服務(wù)器后,我們?nèi)绾悟?yàn)證上傳是否成功,內(nèi)容是否正確呢?出于驗(yàn)證目的,我硬編碼了一個(gè)銷售訂單 ID 55824.文件上傳成功后,我在 SAP CRM 系統(tǒng)里,將上傳的文件創(chuàng)建為該銷售訂單的一個(gè)附件。
(7) 調(diào)用原生 API XMLHttpRequest 的 send 方法,把表單數(shù)據(jù)傳送到 ABAP 服務(wù)器。
打開這個(gè) HTML 文件,如下圖所示,點(diǎn)擊超鏈接進(jìn)行文件上傳。
待上傳的文本文件內(nèi)容如下:
ABAP 后端實(shí)現(xiàn)
因?yàn)槲覀儾唤柚魏魏蠖丝蚣?#xff0c;這意味著我們必須基于最底層的 HTTP 協(xié)議,自行解析出客戶端發(fā)送過(guò)來(lái)的 multipart/form-data 格式的數(shù)據(jù)并進(jìn)行處理。
首先在事物碼 SICF 里,根據(jù)前端代碼里的路徑 sap/crm/file_upload, 新建一個(gè)同樣路徑的處理節(jié)點(diǎn)。
關(guān)于 SICF 的更多介紹,參考 Jerry 的文章:從ABAP Netweaver的SICF到SAP Kyma的Lambda Function.
給這個(gè)節(jié)點(diǎn)創(chuàng)建一個(gè)處理類 ZCL_FILE_UPLOAD, 本文所有的后端處理邏輯,就編寫在這個(gè)類的 HANDLE_REQUEST 內(nèi)。
完整的后端代碼同樣能從這個(gè)鏈接獲得,本文不全部貼出,只介紹要點(diǎn)。
通過(guò)前端 form 表單三個(gè) input 控件維護(hù)的輸入值,加上前端代碼中自定義的表單數(shù)據(jù),被瀏覽器隨機(jī)生成的 FormBoundary 所分隔。提交表單的完整數(shù)據(jù),能夠在 Chrome 開發(fā)者工具 Network 標(biāo)簽頁(yè)里觀察到。
ZCL_FILE_UPLOAD 類的實(shí)現(xiàn)邏輯為,首先解析出瀏覽器發(fā)送過(guò)來(lái)的 FormBoundary 標(biāo)識(shí)符,根據(jù)這個(gè) Boundary,把接收到的表單數(shù)據(jù)拆分成塊,然后只處理我們感興趣的包含本地文件上傳的那一塊。
我們剛剛展示了在 Chrome 開發(fā)者工具里查看發(fā)往 ABAP 服務(wù)器的表單數(shù)據(jù)明細(xì),這些數(shù)據(jù)在 ABAP 服務(wù)器端接收之后,在調(diào)試器里顯示如下:
這些井號(hào)代表什么含義?使用上圖高亮的下拉菜單,把 Fast Display 切換成 HTML Browser,就一目了然了。原來(lái)這些換行符和回車換行符等控制字符,在 ABAP 調(diào)試器里的 Fast Display 視圖里,統(tǒng)一顯示為 “#”號(hào)。
我真正感興趣的上傳文件的實(shí)際內(nèi)容,就存儲(chǔ)在下圖所示這個(gè) form-data 塊里。
因此,我的思路就是,根據(jù)回車換行符定位到上圖 ABAP 變量 LV_DATA 包含的 form-data 塊,如果該塊包含了 content-type:text/plain,就說(shuō)明此塊包含的是上傳文件的實(shí)際內(nèi)容,對(duì)其解析即可得到上傳文件的實(shí)際內(nèi)容。
這里不少新手朋友們常犯的錯(cuò)誤是,因?yàn)樵?ABAP 調(diào)試器里觀察到的回車換行符顯示為“##”,因此在代碼里,這些朋友也直接用單井號(hào)或者雙井號(hào)進(jìn)行字符串匹配,這當(dāng)然無(wú)法工作。
在 ABAP 里要進(jìn)行和換行符以及回車換行符相關(guān)操作,需要使用 ABAP 工具類 CL_ABAP_CHAR_UTILITIES 定義的常量:CR_LF 和 NEWLINE:
正如我本文實(shí)現(xiàn)代碼里的使用方式:
解析出上傳的文本文件內(nèi)容后,調(diào)用 SAP CRM 附件創(chuàng)建 API,將該文件內(nèi)容作為一個(gè)附件,添加到系統(tǒng) ID 為 55824 的銷售訂單中去。
本例為了簡(jiǎn)化起見(jiàn),只支持類型為文本(text/plain)的本地文件上傳成銷售訂單(其 BOR 類型為 BUS20000115)的附件,故文件類型和 BOR 類型都進(jìn)行了硬編碼。
前后端開發(fā)完成之后,進(jìn)行測(cè)試,從本地上傳一個(gè)名為 upload.txt 的文本文件,ABAP 服務(wù)器接收到之后,將其存儲(chǔ)成為銷售訂單 55824 的一個(gè)附件。
點(diǎn)擊附件超鏈接,打開該文件內(nèi)容,發(fā)現(xiàn)和本地文件完全一致,測(cè)試通過(guò):
當(dāng)然,本文描述的實(shí)際是一個(gè)重新造輪子的場(chǎng)景。大家在實(shí)際項(xiàng)目開發(fā)中,如果沒(méi)有特殊原因,還是盡量采用 SAP 提供的現(xiàn)成框架和工具,來(lái)完成諸如文件上傳這種比較基礎(chǔ)和底層的工作,從而把精力放到業(yè)務(wù)邏輯的編寫中去。
感謝閱讀。
Jerry 的 ABAP 專題
-
Jerry的ABAP, Java和JavaScript亂燉
-
ABAP開發(fā)人員未來(lái)應(yīng)該學(xué)些什么
-
Jerry 2017年的五一小長(zhǎng)假:8種經(jīng)典排序算法的ABAP實(shí)現(xiàn)
-
Jerry的ABAP原創(chuàng)技術(shù)文章合集
-
300行ABAP代碼實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的區(qū)塊鏈原型
-
使用Java+SAP云平臺(tái)+SAP Cloud Connector調(diào)用ABAP On-Premise系統(tǒng)里的函數(shù)
-
在SAP云平臺(tái)的CloudFoundry環(huán)境下消費(fèi)ABAP On-Premise OData服務(wù)
-
ABAP vs Java, 蛙泳 vs 自由泳
-
聊聊C語(yǔ)言和ABAP
-
動(dòng)手使用ABAP Channel開發(fā)一些小工具,提升日常工作效率
-
我用ABAP做過(guò)的那些無(wú)聊的事情
-
不喜歡SAP GUI?那試試用Eclipse進(jìn)行ABAP開發(fā)吧
-
使用Visual Studio Code編寫和激活A(yù)BAP代碼
-
你的ABAP程序給佛祖開過(guò)光么?來(lái)試試Jerry這個(gè)小技巧
-
在SAP云平臺(tái)ABAP編程環(huán)境上編寫第一段ABAP程序
-
SAP官方發(fā)布的ABAP編程規(guī)范
-
ABAP Code Inspector那些隱藏的功能,您都知道嗎?
-
還在用ABAP進(jìn)行SAP產(chǎn)品的二次開發(fā)?來(lái)了解下這種全新的二次開發(fā)理念吧
-
ABAP Netweaver體內(nèi)的那些寄生式編程語(yǔ)言
-
從SAP社區(qū)上的一篇博客開始,聊聊SAP產(chǎn)品命名背后的那份情懷
-
云端的ABAP Restful服務(wù)開發(fā)
-
如何在SAP云平臺(tái)ABAP編程環(huán)境里把CDS view暴露成OData服務(wù)
-
使用abapGit在ABAP On-Premises系統(tǒng)和SAP云平臺(tái)ABAP環(huán)境之間進(jìn)行代碼傳輸
-
30分鐘用Restful ABAP Programming模型開發(fā)一個(gè)支持增刪改查的Fiori應(yīng)用
-
Jerry帶您了解Restful ABAP Programming模型系列之二:Action和Validation的實(shí)現(xiàn)
-
Jerry帶您了解Restful ABAP Programming模型系列之三:云端ABAP應(yīng)用調(diào)試
-
SAP云平臺(tái)上的ABAP編程環(huán)境里如何消費(fèi)第三方服務(wù)
-
ABAP開發(fā)者上云的時(shí)候到了 - 現(xiàn)在大家可以免費(fèi)使用SAP云平臺(tái)ABAP環(huán)境的試用版了
-
學(xué)而不思則罔 - SAP云平臺(tái)ABAP編程環(huán)境的由來(lái)和適用場(chǎng)景
-
SAP云平臺(tái)里的三叉戟應(yīng)用
-
如何基于Restful ABAP Programming模型開發(fā)并部署一個(gè)支持增刪改查的Fiori應(yīng)用
-
SAP 2019 TechEd Key Note解讀:云時(shí)代下SAP從業(yè)人員如何做二次開發(fā)?
-
有哪些ABAP關(guān)鍵字和語(yǔ)法,到了ABAP云環(huán)境上就沒(méi)辦法用了?
-
ABAP開發(fā)環(huán)境終于支持以駝峰命名法自動(dòng)格式化ABAP變量名了
-
利用ABAP 740的新關(guān)鍵字REDUCE完成一個(gè)實(shí)際工作任務(wù)
-
一段讓人瑟瑟發(fā)抖的ABAP代碼
-
昨日萬(wàn)圣節(jié)ABAP怪獸級(jí)代碼謎團(tuán),公布答案啦
-
介紹一種在ABAP內(nèi)核態(tài)進(jìn)行內(nèi)表高效拷貝的方法
-
使用SAP Cloud Application Programming模型開發(fā)OData的一個(gè)實(shí)際例子
-
當(dāng)ABAP遇見(jiàn)普羅米修斯
-
使用ABAP繪制可伸縮矢量圖
-
ABAP開發(fā)環(huán)境語(yǔ)法高亮的那些事兒
-
SAP錯(cuò)誤消息調(diào)試之七種武器:讓所有的錯(cuò)誤消息都能被定位
-
使用ABAP操作Excel的幾種方法
-
SAP GUI里的收藏夾事務(wù)碼管理工具
-
SAP GUI和Windows注冊(cè)表
-
有了Debug權(quán)限就能干壞事?小心了,你的一舉一動(dòng)盡在系統(tǒng)監(jiān)控中
-
ABAP CCDEF, CCIMP, CCMAC, CCAU, CMXXX這些東東是什么鬼
-
實(shí)現(xiàn)ABAP條件斷點(diǎn)的三種方式
-
使用SAT跟蹤監(jiān)控從瀏覽器打開的SAP應(yīng)用的性能和調(diào)用棧
-
一個(gè)13年ABAP老兵的建議:了解這些基礎(chǔ)知識(shí),對(duì)ABAP開發(fā)有百利而無(wú)一害
-
SAP ABAP Netweaver容器化, 不可能完成的任務(wù)嗎?
-
SAP產(chǎn)品增強(qiáng)技術(shù)回顧
-
SAP API開發(fā)方法大全
-
淺談Java和SAP ABAP的靜態(tài)代理和動(dòng)態(tài)代理,以及ABAP面向切面編程的嘗試
-
SAP ABAP應(yīng)用服務(wù)器的HTTP響應(yīng)狀態(tài)碼(Status Code)
-
SAP ABAP里存在Java List這種集合工具類么?CL_OBJECT_COLLECTION了解一下
-
ABAP面試題系列:寫一組會(huì)出現(xiàn)死鎖(Deadlock)的ABAP程序
-
SAP ABAP Netweaver服務(wù)器的標(biāo)準(zhǔn)登錄方式講解
-
SAP ABAP關(guān)鍵字語(yǔ)法圖和ABAP代碼自動(dòng)生成工具Code Composer
-
SAP ABAP SM50的另類用途 - ABAP工作進(jìn)程對(duì)數(shù)據(jù)庫(kù)表讀取操作的檢測(cè)
-
關(guān)于SAP ABAP字符變量和字符串變量字符個(gè)數(shù)的一個(gè)知識(shí)點(diǎn),和一個(gè)血案
-
SAP ABAP一組關(guān)鍵字 IS BOUND, IS NOT INITIAL和IS ASSIGNED的用法辨析
-
SAP ABAP和Java里的弱引用(WeakReference)和軟引用(SoftReference)
-
SAP AMDP介紹 - ABAP托管的HANA數(shù)據(jù)庫(kù)過(guò)程
-
給你的ABAP對(duì)象打上標(biāo)簽(Tag)
-
歷史上的今天:編程語(yǔ)言中null引用的十億美元錯(cuò)誤
-
ABAP Development Tool 代碼模板和其他一些實(shí)用技巧匯總
-
SAP ABAP Development Tool 提高開發(fā)效率的十個(gè)小技巧
-
如何在 SAP BTP 平臺(tái) ABAP 編程環(huán)境里消費(fèi)基于 SOAP 的 Web Service
-
ABAP 真的會(huì)過(guò)時(shí)嗎?聊聊 ABAP 的過(guò)去,現(xiàn)在和未來(lái)
-
基于 abapGit 和 abaplint 的 ABAP 持續(xù)集成的一個(gè)例子
更多Jerry的原創(chuàng)文章,盡在:“汪子熙”:
總結(jié)
以上是生活随笔為你收集整理的不使用任何框架,手写纯 JavaScript 实现上传本地文件到 ABAP 服务器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 帧率提升 77%,MOD 开发者为《星球
- 下一篇: 什么是 JavaScript 世界的 U