此帖主要講解通過開發文檔示例代碼寫一個完整 Demo,方便初學者理解開發文檔內容。
大家都知道 3.0 使用的是 FA 模式、3.1 使用的是 Stage 模式,所以同樣是文件上傳,代碼寫法上有些不一樣,開發文檔也不一樣。
比如在 3.1 下,可以在 HarmonyOS Developer > 文檔 > 指南 > 開發下找到文件上傳下載示例代碼。
而在 3.0 下,就找不到相應指南開發了,只能在 HarmonyOS Developer > 文檔 > API 參考 > ArkTS API 參考找到 @ohos.request (上傳下載)文檔。
為了實現一個完整文件上傳 Demo,后端是少不了的,這里我使用了我平常工作中用到的 SpringBoot 開發后端。
為了驗證文件上傳接口是否正常,使用 Thymeleaf 寫一個簡單的前端頁面來測試接口,先保證后端文件上傳接口是正常的。
這樣其它前端調用就可以排除后端文件上傳接口問題,專心調試前端代碼,希望小伙伴通過此貼學習到文件上傳同時,參考此思路也可以自己完成其它示例代碼完成 Demo。
效果如下:
ArkTS(3.0)文件管理(前端)
此版本使用的是 FA 模式、配置文件名是 config.json 由于文件上傳需要網絡,需要添加權限:ohos.permission.INTERNET,默認支持 https。
如果要支持 http,需要在 config.json 里增加 network 標簽,屬性標識 “cleartextTraffic”: true。
所以 config.json 要添加的內容以下:
{ "app":{...}, "deviceConfig":{ "default":{ "network":{ "cleartextTraffic":true } } }, "module":{ "reqPermissions":[ { "name":"ohos.permission.INTERNET" } ] } }文件上傳頁面就一個 index.ets 文件,里面包含 UI 和調用后端接口,代碼如下:
importrequestfrom'@ohos.request'; importfeatureAbilityfrom'@ohos.ability.featureAbility'; importfileiofrom'@ohos.fileio'; @Entry @Component structIndex{ @StatebtnLabel:string='提交文件' privateuploadTask:request.UploadTask aboutToAppear(){ //獲取應用文件路徑 varcontext=featureAbility.getContext(); context.getCacheDir().then((data)=>{ console.info("xx======================>getCacheDirPromsie====================>"); console.info("xx====>data====>"+JSON.stringify(data)); //新建一個本地應用文件 letfd=fileio.openSync(data+'/test.txt',0o102,0o666); fileio.writeSync(fd,'uploadfiletestbyarmy'); fileio.closeSync(fd); }); } aboutToDisappear(){ this.uploadTask.off("progress") } uploadFile(){ //上傳任務配置項 letuploadConfig={ url:'http://111.114.238.134:8740/file/upload', header:{key1:'Content-Type',key2:'multipart/form-data'}, method:'POST', files:[ {filename:'test.txt',name:'test',uri:'internal://cache/test.txt',type:'txt'} ], data:[ {name:'fileId',value:'FP000008'} ] } //將本地應用文件上傳至網絡服務器 try{ this.btnLabel='文件上傳中...' request.upload(uploadConfig) .then((data)=>{ this.btnLabel='文件上傳成功' this.uploadTask=data console.info('xxSuccesstorequesttheupload.Cause:'+JSON.stringify(data)); //uploadTask=data; this.uploadTask.on("progress",(uploadedSize,totalSize)=>{ console.info('xx上傳進度值是:'+uploadedSize+',總大小:'+totalSize) }) }).catch((err)=>{ this.btnLabel='文件上傳失敗' console.error('xxFailedtorequesttheupload.Cause:'+JSON.stringify(err)); }) }catch(err){ this.btnLabel='文件上傳失敗' console.error(`xxInvokeuploadFilefailed,codeis${err.code},messageis${err.message}`); } } build(){ Column({space:30}){ Text('上傳文件實例:') .width('100%') .height(50) .fontSize(24) .textAlign(TextAlign.Center) Button('提交文件') .onClick(()=>{ this.uploadFile() }) .width('80%') .height(50) .fontSize(24) }.width('100%').height('100%') .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) } }
ArkTS(3.1)文件管理(前端)
此版本使用的是 Stage 模式、配置文件名是 module.json5 由于文件上傳需要網絡,需要添加權限:ohos.permission.INTERNET。
在 3.1 不用配置,就支持 http 和 https,當前上傳應用文件功能,僅支持上傳應用緩存文件路徑(cacheDir)下的文件。
所以 module.json5 要添加的內容以下:
{ "module":{ "requestPermissions":[ { "name":"ohos.permission.INTERNET" } ] } }文件上傳頁面就一個 index.ets 文件,里面包含 UI 和調用后端接口,代碼如下:
importcommonfrom'@ohos.app.ability.common'; importfsfrom'@ohos.file.fs'; importrequestfrom'@ohos.request'; importhashfrom'@ohos.file.hash'; //獲取應用文件路徑 letcontext=getContext(this)ascommon.UIAbilityContext; @Entry @Component structIndex{ @StatebtnLabel:string='提交文件' privateuploadTask:request.UploadTask aboutToAppear(){ letcacheDir=context.cacheDir; //新建一個本地應用文件 letfile=fs.openSync(cacheDir+'/test.txt',fs.OpenMode.READ_WRITE|fs.OpenMode.CREATE); fs.writeSync(file.fd,'uploadfiletestbyAPI9'); fs.closeSync(file); } aboutToDisappear(){ this.uploadTask.off("complete") } uploadFile(){ //上傳任務配置項 letuploadConfig={ url:'http://111.114.238.134:8740/file/upload', header:{key1:'Content-Type',key2:'multipart/form-data'}, method:'POST', files:[ {filename:'test.txt',name:'test',uri:'internal://cache/test.txt',type:'txt'} ], data:[ {name:'fileId',value:'FP000008'} ] } //將本地應用文件上傳至網絡服務器 try{ this.btnLabel='文件上傳中...' request.uploadFile(context,uploadConfig) .then((data)=>{ this.btnLabel='文件上傳成功' this.uploadTask=data this.uploadTask.on('complete',(taskStates)=>{ for(leti=0;i{ this.btnLabel='文件上傳失敗' console.error(`xxInvokeuploadFilefailed,codeis${err.code},messageis${err.message}`); }) }catch(err){ this.btnLabel='文件上傳失敗' console.error(`xxInvokeuploadFilefailed,codeis${err.code},messageis${err.message}`); } } build(){ Column({space:30}){ Text('上傳文件實例:') .width('100%') .height(50) .fontSize(24) .textAlign(TextAlign.Center) Button(this.btnLabel) .onClick(()=>{ this.uploadFile() }) .width('80%') .height(50) .fontSize(24) } .width('100%').height('100%') .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) } }
SpringBoot 和 Thymeleaf(后端)
后端首先列出 pom.xml 文件,里面包含項目依賴jar配置,比如 web、thymeleaf 依賴。
內容如下:
4.0.0 org.springframework.boot spring-boot-starter-parent 2.3.1.RELEASE com.army file-manage 0.0.1-SNAPSHOT file-manage DemoprojectforSpringBoot 8 org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-web org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test commons-io commons-io 2.6 org.springframework.boot spring-boot-maven-plugin org.projectlombok lombok前端調用接口文件 Controller 代碼如下:
@RestController @RequestMapping("/file") @Slf4j publicclassFileController{ @Autowired FileServicefileService; @PostMapping("/upload") publicStandardResponseupload(StringfileId,MultipartHttpServletRequestmultiPartRequest){ log.info("**UploadFileController!"); FileCriteriacriteria=newFileCriteria(); criteria.setFileId(fileId); try{ //uploadfile Iteratoritr=multiPartRequest.getFileNames(); MultipartFilempf=null; while(itr.hasNext()){ mpf=multiPartRequest.getFile(itr.next()); break; } byte[]fileByteArr=null; if(null!=mpf&&!mpf.isEmpty()){ StringoriginalFileName=mpf.getOriginalFilename(); log.info(originalFileName); criteria.setFileName(""); StringfileExtension=FilenameUtils.getExtension(originalFileName); criteria.setFileExtension(fileExtension); fileByteArr=mpf.getBytes(); criteria.setFileByteArray(fileByteArr); criteria.setFileName(originalFileName); } }catch(IOExceptione){ e.printStackTrace(); log.error(e.getMessage()); } returnfileService.uploadFile(criteria); } }
后端業務邏輯代碼,也就是文件上傳處理邏輯 Service 代碼如下:
業務接口:
publicinterfaceFileService{ StandardResponseuploadFile(FileCriteriacriteria); StringsaveFile(FileCriteriacriteria); }業務實現類:
@Service @Slf4j publicclassFileServiceImplimplementsFileService{ @Value("${project.root.path}") privateStringrootPath="rootPath"; @Value("${project.baseUrl}") privateStringbaseUrl; @Override publicStandardResponseuploadFile(FileCriteriacriteria){ StringfilePath=this.saveFile(criteria); StringimgPath=baseUrl+"filePath/"+filePath; StandardResponsestandardResponse=newStandardResponse(); standardResponse.setSuccess(true); standardResponse.setStatusCode("100"); standardResponse.setStatusDesc("上傳成功"); standardResponse.setData(imgPath); returnstandardResponse; } @Override publicStringsaveFile(FileCriteriacriteria){ log.info("上傳文件開始!"); StringpictureId=IdUtils.getId("FP"); StringfileName=pictureId+"."+criteria.getFileExtension(); criteria.setFileName(fileName); StringfilePath=sourceFile(criteria); log.info("FilePath:"+filePath); log.info("上傳文件結束!"); returnfilePath; } privateStringsourceFile(FileCriteriacriteria){ byte[]attachmentFileByteArray=criteria.getFileByteArray(); if(null!=attachmentFileByteArray){ log.info("1.1.創建根目錄."); StringbasePath=rootPath+this.genDatePath(); FilebasePathFolder=newFile(basePath); if(!basePathFolder.exists())basePathFolder.mkdirs(); log.info("根目錄:"+basePath); Filefile=newFile(basePath+File.separator+criteria.getFileName()); log.info("1.2.保存源文件-絕對路徑:"+file.getAbsolutePath()); try{ FileCopyUtils.copy(attachmentFileByteArray,file); log.info("1.3.1.保存源文件-保存成功!!!"); StringrelativePath=this.genDatePath()+File.separator+criteria.getFileName(); returnrelativePath; }catch(IOExceptione){ log.info("1.3.2.保存源文件-保存失敗!!!"); file.deleteOnExit(); return""; } } return""; } privateStringgenDatePath(){ SimpleDateFormatsdf=newSimpleDateFormat("yyyyMMdd"); StringyyyyMMdd=sdf.format(newDate()); returnyyyyMMdd; } }配置文件:
server: port:8740 project: root: path:/var/tomcat/file-manage/filePath/ baseUrl:http://111.114.238.134:8740/訪問域名或 IP 加端口訪問到 Thymeleaf 頁面,要添加一個 Controller 跳轉。
@Controller publicclassIndexController{ @GetMapping("/") publicStringIndex(){ return"index"; } }
在 templates 目錄下創建 index.htm 頁面文件,這里的 index 名要和上面 Controller 返回“index”名一致,才能跳轉過去。
index.html 代碼如下:
單文件上傳
上面圖片就是 Thymeleaf 頁面,上傳文件成功后效果。
總結
通過此貼學習到文件上傳 3.0 與 3.1 的不同處,同時也學習到了后端開發流程。 其實寫這個貼子之前,是一個小伙伴問到我關于文件上傳問題,由于之前我寫的實例里,也沒有用到文件上傳功能,于是我就用最新 API9 也就是 Stage 模式寫了一個 Demo 給他參考,然后他通過參考我的 Demo,學會了。 可惜他現在開發的項目是用 API8 的,由于開發模式不一樣,他遇到了問題,于是我在用 API8 寫了一個 Demo 給他參考,最后他的項目也實現了文件上傳。
審核編輯:湯梓紅
-
接口
+關注
關注
33文章
8611瀏覽量
151237 -
API
+關注
關注
2文章
1502瀏覽量
62071 -
開發者
+關注
關注
1文章
577瀏覽量
17021 -
鴻蒙
+關注
關注
57文章
2358瀏覽量
42871 -
HarmonyOS
+關注
關注
79文章
1977瀏覽量
30229
原文標題:鴻蒙上實現“文件上傳”功能
文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論