spring boot如何实现切割分片上传
这篇文章主要介绍了springboot如何实现切割分片上传,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
文件上传是web开发中经常会遇到的
springboot的默认配置为10MB,大于10M的是传不上服务器的,需要修改默认配置
但是如果修改支持大文件又会增加服务器的负担。
当文件大于一定程度时,不仅服务器会占用大量内存,而且http传输极可能会中断。
可以采用切割分片上传
html5提供的文件API中可以轻松的对文件进行分割切片,然后通过ajax异步处理向服务器传输数据,突破对大文件上传的限制,
同时异步处理在一定程度上也提高了文件上传的效率。
过程描述:
- 将文件分割成N片
- 处理分片,前台会多次调用上传接口,每次都会上传文件的一部分到服务端
- N个分片都上传完成后,将N个文件合并为一个文件,并将N个分片文件删除
1.服务端
(1)添加依赖
commons-fileupload commons-fileupload 1.3.3
(2)UploadController
packagecom.example.demo.controller; importcom.example.demo.core.Result; importorg.apache.commons.fileupload.servlet.ServletFileUpload; importorg.apache.commons.io.FileUtils; importorg.springframework.stereotype.Controller; importorg.springframework.web.bind.annotation.CrossOrigin; importorg.springframework.web.bind.annotation.PostMapping; importorg.springframework.web.bind.annotation.RequestMapping; importorg.springframework.web.bind.annotation.ResponseBody; importorg.springframework.web.multipart.MultipartFile; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importjava.io.File; importjava.io.FileOutputStream; importjava.io.IOException; importjava.text.SimpleDateFormat; importjava.util.Date; @CrossOrigin @Controller @RequestMapping("/api/upload") publicclassUploadController{ @PostMapping("/part") @ResponseBody publicResultbigFile(HttpServletRequestrequest,HttpServletResponseresponse,Stringguid,Integerchunk,MultipartFilefile,Integerchunks){ try{ StringprojectUrl=System.getProperty("user.dir").replaceAll("\\\\","/"); ; booleanisMultipart=ServletFileUpload.isMultipartContent(request); if(isMultipart){ if(chunk==null)chunk=0; //临时目录用来存放所有分片文件 StringtempFileDir=projectUrl+"/upload/"+guid; FileparentFileDir=newFile(tempFileDir); if(!parentFileDir.exists()){ parentFileDir.mkdirs(); } //分片处理时,前台会多次调用上传接口,每次都会上传文件的一部分到后台 FiletempPartFile=newFile(parentFileDir,guid+"_"+chunk+".part"); FileUtils.copyInputStreamToFile(file.getInputStream(),tempPartFile); } }catch(Exceptione){ returnResult.failMessage(400,e.getMessage()); } returnResult.successMessage(200,"上次成功"); } @RequestMapping("merge") @ResponseBody publicResultmergeFile(Stringguid,StringfileName){ //得到destTempFile就是最终的文件 StringprojectUrl=System.getProperty("user.dir").replaceAll("\\\\","/"); try{ Stringsname=fileName.substring(fileName.lastIndexOf(".")); //时间格式化格式 DatecurrentTime=newDate(); SimpleDateFormatsimpleDateFormat=newSimpleDateFormat("yyyyMMddHHmmssSSS"); //获取当前时间并作为时间戳 StringtimeStamp=simpleDateFormat.format(currentTime); //拼接新的文件名 StringnewName=timeStamp+sname; simpleDateFormat=newSimpleDateFormat("yyyyMM"); Stringpath=projectUrl+"/upload/"; Stringtmp=simpleDateFormat.format(currentTime); FileparentFileDir=newFile(path+guid); if(parentFileDir.isDirectory()){ FiledestTempFile=newFile(path+tmp,newName); if(!destTempFile.exists()){ //先得到文件的上级目录,并创建上级目录,在创建文件 destTempFile.getParentFile().mkdir(); try{ destTempFile.createNewFile(); }catch(IOExceptione){ e.printStackTrace(); } } for(inti=0;i说明:
注解@CrossOrigin解决跨域问题
(3)Result
packagecom.example.demo.core; importcom.alibaba.fastjson.JSON; /** *CreatedbyBeibeion19/02/22 *API响应结果 */ publicclassResult{ privateintcode; privateStringmessage; privateTdata; publicResultsetCode(Integercode){ this.code=code; returnthis; } publicintgetCode(){ returncode; } publicStringgetMessage(){ returnmessage; } publicResultsetMessage(Stringmessage){ this.message=message; returnthis; } publicTgetData(){ returndata; } publicResultsetData(Tdata){ this.data=data; returnthis; } @Override publicStringtoString(){ returnJSON.toJSONString(this); } publicstatic Result fail(Integercode,Tdata){ Result ret=newResult (); ret.setCode(code); ret.setData(data); returnret; } publicstatic Result failMessage(Integercode,Stringmsg){ Result ret=newResult (); ret.setCode(code); ret.setMessage(msg); returnret; } publicstatic Result successMessage(Integercode,Stringmsg){ Result ret=newResult (); ret.setCode(code); ret.setMessage(msg); returnret; } publicstatic Result success(Integercode,Tdata){ Result ret=newResult (); ret.setCode(code); ret.setData(data); returnret; } } 2.前端
(1)使用插件
webuploader,下载 https://github.com/fex-team/webuploader/releases
选择文件