这篇文章给大家分享的是有关springboot如何实现带有进度条的上传功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
十多年的凭祥网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。成都全网营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整凭祥建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联建站从事“凭祥网站设计”,“凭祥网站推广”以来,每个客户项目都认真落实执行。
一、说明
最近要做文件上传,在网上找了很久都没有一个全面的示例,特此记录下来分享给大家。
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:/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);
}感谢各位的阅读!关于“springboot如何实现带有进度条的上传功能”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
分享文章:springboot如何实现带有进度条的上传功能
链接分享:http://www.jxjierui.cn/article/jhhscs.html


咨询
建站咨询
