栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springboot带有进度条的上传功能完整实例

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springboot带有进度条的上传功能完整实例

本文实例讲述了springboot带有进度条的上传功能。分享给大家供大家参考,具体如下:

一、说明

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

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

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

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

二、前端代码





文件上传




  

0KB/s


效果:

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

UploadCommon.js


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:/tmp
debug: 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
@EnableTransactionManagement
public 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-8
spring: 
 application: 
  name: svc-demo
 thymeleaf: 
  encoding: UTF-8
  cache: false
  mode: LEGACYHTML5
debug: 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;
  }
}

监听类

@Component
public 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);
    }
  }
}

控制器

@RestController
public 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 })
@SpringBootApplication
public 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);
  }

更多关于java相关内容感兴趣的读者可查看本站专题:《Spring框架入门与进阶教程》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/136432.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号