千家信息网

如何实现springboot带有进度条的上传功能

发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,这篇文章将为大家详细讲解有关如何实现springboot带有进度条的上传功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体如下:一、说明最近要做文件上传,在网上
千家信息网最后更新 2025年01月31日如何实现springboot带有进度条的上传功能

这篇文章将为大家详细讲解有关如何实现springboot带有进度条的上传功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

具体如下:

一、说明

  最近要做文件上传,在网上找了很久都没有一个全面的示例,特此记录下来分享给大家。

  1.文件上传接口可按照springboot默认实现,也可用commons-fileupload组件,本示例使用springboot默认文件上传 2.最后也有commons-fileupload组件接口示例

  2.重点在前端JS实现(也可以使用ajax上传),参考了网上大量上传文件显示进度条博客以及技术方案,在此做了一个统一的总结,方便后续使用

  3.这仅仅是一个示例,大家可根据实际需要改进。

二、前端代码

文件上传  


0KB/s




三、对上传代码进行组件化封装

UploadCommon.js

/** * 上传文件公共组件 *  * @param url 上传地址 * @param processBar 进度条 jquery获取的页面组件 * @param speedLab 显示上传速度Label jquery获取的页面组件 * @param uploadBtn 上传按钮 jquery获取的页面组件 * @param cancelBtn 取消上传按钮 jquery获取的页面组件 * @param callBack 上传完成回调函数 上传完成后的回调函数,可以不传 * @author * @returns */function UploadCommon(url, processBar, speedLab, uploadBtn, cancelBtn, callBack){  function init() {    // 每次回调监测上传开始时间    var startTime = null    // 已上传文件大小    var oloaded = null     var xhr = new XMLHttpRequest()    function setProgress(w) {      processBar.width(w + '%');      processBar.text(w + '%');    }    function progressMonitor(evt){      if (evt.lengthComputable) {        var completePercent = Math.round(evt.loaded / evt.total * 100)        setProgress(completePercent)        var nowTime = new Date().getTime()        // 计算出上次调用该方法时到现在的时间差,单位为s        var pertime = (nowTime - startTime) / 1000           // 重新赋值时间,用于下次计算        startTime = new Date().getTime()        // 计算该分段上传的文件大小,单位b        var perload = evt.loaded - oloaded        // 重新赋值已上传文件大小,用以下次计算        oloaded = evt.loaded        // 上传速度计算,单位b/s        var speed = perload / pertime        var bspeed = speed        // 单位名称        var units = 'bit/s'if (speed / 1024 > 1) {          speed = speed / 1024          units = 'Kb/s'        }        if (speed / 1024 > 1) {          speed = speed / 1024          units = 'Mb/s'        }        speed = speed.toFixed(1);        // 剩余时间        var resttime = ((evt.total - evt.loaded) / bspeed).toFixed(1)        speedLab.html(speed + units + ',剩余时间:' + resttime + 's')      }    }    // 上传成功后回调    function uploadComplete(evt) {      uploadBtn.attr('disabled', false)      var status = evt.currentTarget.status      if (status == 401) {        alert('请登录后再上传')        return      }      if (status == 403) {        alert('无权限操作')        return      }      if (status != 200) {        alert('上传异常,错误码' + status)        return      }      var response=JSON.parse(evt.currentTarget.response)      if (response.code!='200') {        alert('上传处理异常' + response.msg)        return      }      console.log('上传成功')      if ( callBack != null && typeof callBack != 'undefined') {        callBack()      }    };    // 上传失败回调    function uploadFailed(evt) {      alert('上传处理失败' + evt.target.responseText)    }    // 终止上传    function cancelUpload() {      xhr.abort()    }    // 上传取消后回调    function uploadCanceled(evt) {      alert('文件上传已终止:' + evt.target.responseText)    }    // 添加取消上传事件    cancelBtn.click(function() {          uploadBtn.attr('disabled', false)          cancelUpload();        })    this.uploadFile = function(formData) {      // 上传按钮禁用      uploadBtn.attr('disabled', true);      setProgress(0)      // true为异步处理      xhr.open('post', url, true)      // 上传开始执行方法      xhr.onloadstart = function() {        console.log('开始上传')        // 设置上传开始时间        startTime = new Date().getTime()         // 已上传的文件大小为0        oloaded = 0       }      xhr.upload.addEventListener('progress', progressMonitor, false)      xhr.addEventListener("load", uploadComplete, false)      xhr.addEventListener("error", uploadFailed, false)      xhr.addEventListener("abort", uploadCanceled, false)      xhr.send(formData);    }    this.setProgressValue=function(w){      processBar.width(w + '%')      processBar.text(w + '%')    }  }  return new init()}

调用

$(document).ready(function() {  var addVersionBtn=$('#addVersionBtn') //

四,服务端接口

1.springboot默认实现

pom.xml

  4.0.0  com.demo  demo  0.0.1-SNAPSHOT      org.springframework.boot    spring-boot-starter-parent    1.5.10.RELEASE            UTF-8    UTF-8    1.8              org.springframework.boot      spring-boot-devtools      true              org.springframework.boot      spring-boot-starter-web              org.springframework.boot      spring-boot-starter-thymeleaf               net.sourceforge.nekohtml       nekohtml              org.springframework.boot      spring-boot-starter-test      test                  io.springfox      springfox-swagger2      2.7.0              io.springfox      springfox-swagger-ui      2.7.0                              org.springframework.boot        spring-boot-maven-plugin            

application.yml

server: port: 8080 tomcat: uri-encoding: UTF-8 application: name: demo thymeleaf: encoding: UTF-8 cache: true mode: LEGACYHTML5 devtools: restart: enabled: true http: multipart: maxFileSize: 500Mb maxRequestSize: 500Mb location: D:/tmpdebug: false

接口:

@PostMapping("/upload")public String uploadFile(@RequestParam("file") MultipartFile file) { if (file == null || file.isEmpty()) { return "file is empty"; } // 获取文件名 String fileName = file.getOriginalFilename(); // 文件存储路径 String filePath = "D:/data/" + UUID.randomUUID().toString().replaceAll("-", "") + "_" + fileName; logger.info("save file to:" + filePath); File dest = new File(filePath); if (!dest.getParentFile().exists()) { dest.getParentFile().mkdirs(); } try { file.transferTo(dest); return "success"; } catch (Exception e) { e.printStackTrace(); } return "fail"; }

启动类

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.builder.SpringApplicationBuilder;import org.springframework.boot.web.support.SpringBootServletInitializer;import org.springframework.transaction.annotation.EnableTransactionManagement;@SpringBootApplication@EnableTransactionManagementpublic class Application extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } public static void main(String[] args) { SpringApplication.run(Application.class, args); }}

2.使用commons-fileupload上传组件

application.yml

server: port: 8080 tomcat: uri-encoding : UTF-8spring: application: name: svc-demo thymeleaf: encoding: UTF-8 cache: false mode: LEGACYHTML5debug: false

pom .xml

org.springframework.boot spring-boot-starter-parent 1.5.10.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-devtools true org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-test test commons-io commons-io 2.4 commons-fileupload commons-fileupload 1.3.1 net.sourceforge.nekohtml nekohtml org.springframework.boot spring-boot-maven-plugin

进程类

public class Progress{ private long bytesRead; //已读取文件的比特数 private long contentLength;//文件总比特数 private long items; //正读的第几个文件 public long getBytesRead(){ return bytesRead; } public void setBytesRead(long bytesRead){ this.bytesRead = bytesRead; } public long getContentLength() { return contentLength; } public void setContentLength(long contentLength) { this.contentLength = contentLength; } public long getItems() { return items; } public void setItems(long items)\{ this.items = items; }}

监听类

@Componentpublic class FileUploadProgressListener implements ProgressListener{ private HttpSession session; public void setSession(HttpSession session){ this.session=session; Progress status = new Progress();//保存上传状态 session.setAttribute("status", status); } @Override public void update(long bytesRead, long contentLength, int items) { Progress status = (Progress) session.getAttribute("status"); status.setBytesRead(bytesRead); status.setContentLength(contentLength); status.setItems(items); }}

文件上传处理类

public class CustomMultipartResolver extends CommonsMultipartResolver{ // 注入第二步写的FileUploadProgressListener @Autowired private FileUploadProgressListener progressListener; public void setFileUploadProgressListener(FileUploadProgressListener progressListener){ this.progressListener = progressListener; } @Override public MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException{ String encoding = determineEncoding(request); FileUpload fileUpload = prepareFileUpload(encoding);     //fileUpload.setFileSizeMax(1024 * 1024 * 500);// 单个文件最大500M //fileUpload.setSizeMax(1024 * 1024 * 500);// 一次提交总文件最大500M progressListener.setSession(request.getSession());// 问文件上传进度监听器设置session用于存储上传进度 fileUpload.setProgressListener(progressListener);// 将文件上传进度监听器加入到 fileUpload 中 try{ List fileItems = ((ServletFileUpload) fileUpload).parseRequest(request); return parseFileItems(fileItems, encoding); } catch (FileUploadBase.SizeLimitExceededException ex) { throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex); } catch (FileUploadException ex){ throw new MultipartException("Could not parse multipart servlet request", ex); } }}

控制器

@RestControllerpublic class FileController{ @PostMapping("/upload") public String uploadFile(@RequestParam("file") MultipartFile file) { if (file.isEmpty()) { return "文件为空";     } // 获取文件名 String fileName = file.getOriginalFilename();// 文件上传后的路径 // 文件上传后的路径 String filePath = null; try{ filePath = new File("").getCanonicalPath() + "/tmp/uploadFile/"; } catch (IOException e){ e.printStackTrace(); } //存储路径 String tagFilePath = filePath + CommonUtil.getCurrentTime() + fileName; File dest = new File(tagFilePath); // 检测是否存在目录 if (!dest.getParentFile().exists()){ dest.getParentFile().mkdirs(); } try{ file.transferTo(dest); } catch (IllegalStateException e){ e.printStackTrace(); } catch (IOException e){ e.printStackTrace(); } return fileName + "上传失败"; }}

启动类

//注意取消自动Multipart配置,否则可能在上传接口中拿不到file的值@EnableAutoConfiguration(exclude = { MultipartAutoConfiguration.class })@SpringBootApplicationpublic class Application extends SpringBootServletInitializer{ //注入自定义的文件上传处理类 @Bean(name = "multipartResolver") public MultipartResolver multipartResolver() { CustomMultipartResolver customMultipartResolver = new CustomMultipartResolver(); return customMultipartResolver; } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application){ return application.sources(Application.class); } public static void main(String[] args) { SpringApplication.run(Application.class, args); }

关于"如何实现springboot带有进度条的上传功能"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

0