news 2026/2/3 10:19:08

网页如何设计Java WebUploader分片上传的暂停与继续?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
网页如何设计Java WebUploader分片上传的暂停与继续?

开发者日记:2023年11月20日 周一 晴
项目名称:跨平台大文件传输系统(WebUploader+Vue3+JSP+腾讯云COS)


项目背景与核心挑战

近期承接了一个高难度外包项目,客户要求实现20G级文件/文件夹上传下载,需满足以下硬性条件:

  1. 断点续传:即使重启电脑,进度不能丢失(需持久化存储)
  2. 文件夹层级保留:上传后需100%还原原始目录结构
  3. 全浏览器兼容:从IE8到现代浏览器(Edge/Chrome/Firefox/Safari/Opera)
  4. 技术栈:Vue3(前端)+ JSP(后端)+ MySQL(数据库)+ 腾讯云COS(存储)

现存问题

  • 网上开源方案仅支持单文件上传,无完整文件夹上传实现
  • IE8的Flash上传存在安全策略限制
  • 腾讯云COS的分片上传API与百度OBS有差异,需重新适配
  • 20G文件传输需解决内存溢出和超时问题

技术方案设计

前端架构(Vue3 + WebUploader)
graph TD A[用户选择文件/文件夹] --> B{浏览器类型} B -->|Chrome/Firefox| C[使用webkitdirectory API] B -->|IE8| D[调用ActiveX控件递归读取] C & D --> E[生成文件树结构] E --> F[计算文件MD5(spark-md5)] F --> G[分片上传(WebUploader)] G --> H[本地存储进度(localStorage)]
后端架构(JSP + Servlet)
接收分片
是否首片
创建数据库任务记录
更新分片进度
存储分片到临时目录
是否全部分片完成
合并文件并上传COS
返回继续上传指令
关键数据库设计
CREATETABLEupload_tasks(task_idVARCHAR(36)PRIMARYKEY,-- UUIDfile_md5VARCHAR(64)NOTNULL,relative_pathVARCHAR(512),-- 保留文件夹层级(如 /docs/2023/)total_chunksINT,uploaded_chunksINT,statusENUM('pending','uploading','completed','failed'),cos_keyVARCHAR(1024),-- COS存储路径create_timeDATETIMEDEFAULTNOW());

核心代码实现

前端:文件夹上传与断点续传(Vue3)
// src/components/FolderUploader.vueimport{ref,onMounted}from'vue';importWebUploaderfrom'webuploader';importSparkMD5from'spark-md5';exportdefault{setup(){consttaskList=ref([]);constuploader=ref(null);// 初始化上传器(兼容IE8)constinitUploader=()=>{constisIE8=!!window.ActiveXObject||"ActiveXObject"inwindow;uploader.value=WebUploader.create({swf:'/static/Uploader.swf',// IE8回退server:'/api/upload-chunk',chunked:true,chunkSize:isIE8?4*1024*1024:10*1024*1024,threads:isIE8?1:3,// IE8限制并发formData:{taskId:localStorage.getItem('currentTaskId')||''}});// 恢复未完成任务restoreTasks();};// 递归解析文件夹(跨浏览器)consthandleFolderSelect=(e)=>{constfiles=e.target.files;if(!files.length)return;constparseFolder=(entries,parentPath='')=>{for(letentryofentries){if(entry.isFile){constrelativePath=parentPath?`${parentPath}/${entry.name}`:entry.name;addUploadTask(entry,relativePath);}elseif(entry.isDirectory){constdirReader=entry.createReader();dirReader.readEntries((newEntries)=>{parseFolder(newEntries,parentPath?`${parentPath}/${entry.name}`:entry.name);});}}};// Chrome/Firefox使用webkitGetAsEntryif(files[0].webkitGetAsEntry){constentry=files[0].webkitGetAsEntry();if(entry.isDirectory){constdirReader=entry.createReader();dirReader.readEntries(parseFolder);}else{addUploadTask(files[0],files[0].name);}}// IE8使用ActiveX(代码省略)};// 添加上传任务constaddUploadTask=(file,relativePath)=>{consttask={file,relativePath,md5:'',chunkCount:Math.ceil(file.size/uploader.value.options.chunkSize)};// 计算文件MD5(用于断点校验)calculateFileMD5(file,(md5)=>{task.md5=md5;taskList.value.push(task);saveTaskToLocal(task);});};onMounted(()=>{initUploader();document.getElementById('folderInput').addEventListener('change',handleFolderSelect);});return{taskList,uploader};}};
后端:JSP分片处理与COS上传
// /api/upload-chunk.jsp<%@ pageimport="com.qcloud.cos.COSClient, com.qcloud.cos.model.*"%><%@ pageimport="java.util.UUID, java.io.*"%><%// 1. 获取参数StringtaskId=request.getParameter("taskId");intchunkIndex=Integer.parseInt(request.getParameter("chunkIndex"));inttotalChunks=Integer.parseInt(request.getParameter("totalChunks"));StringfileMd5=request.getParameter("fileMd5");StringrelativePath=request.getParameter("relativePath");// 2. 保存分片StringtempDir=application.getRealPath("/")+"/temp/"+taskId;Filedir=newFile(tempDir);if(!dir.exists())dir.mkdirs();PartfilePart=request.getPart("file");StringchunkPath=tempDir+"/chunk_"+chunkIndex;filePart.write(chunkPath);// 3. 更新数据库try(Connectionconn=DriverManager.getConnection("jdbc:mysql://localhost:3306/file_transfer","user","pass");PreparedStatementstmt=conn.prepareStatement("UPDATE upload_tasks SET uploaded_chunks=? WHERE task_id=?")){stmt.setInt(1,chunkIndex+1);stmt.setString(2,taskId);stmt.executeUpdate();}// 4. 检查是否全部上传完成booleanisComplete=false;try(Connectionconn=DriverManager.getConnection("jdbc:mysql://localhost:3306/file_transfer","user","pass");ResultSetrs=conn.createStatement().executeQuery("SELECT uploaded_chunks, total_chunks FROM upload_tasks WHERE task_id='"+taskId+"'")){if(rs.next()){isComplete=rs.getInt("uploaded_chunks")>=rs.getInt("total_chunks");}}// 5. 合并并上传COSif(isComplete){StringfinalPath=tempDir+"/final_"+fileMd5;mergeChunks(tempDir,finalPath,totalChunks);// 合并逻辑省略// 腾讯云COS上传COSClientcosClient=newCOSClient("secretId","secretKey","region");StringcosKey="uploads/"+taskId+"/"+relativePath;cosClient.putObject(newPutObjectRequest("your-bucket",cosKey,newFile(finalPath)));// 清理临时文件deleteDirectory(newFile(tempDir));}out.print("{\"status\":\"success\"}");%>

关键问题解决

  1. IE8文件夹上传

    • 使用``配合ActiveX的FileSystemObject递归读取
    • 需用户手动设置IE安全级别为"低"(客户要求,已文档说明)
  2. 腾讯云COS分片校验

    • 上传前通过COSObjectdoesObjectExist方法检查分片是否已存在
  3. 20G文件内存优化

    • 采用流式处理,避免一次性加载整个文件到内存
    • JSP设置request.setAttribute("maxPostSize", "21474836480")(20GB)

求助与社区支持

目前IE8的ActiveX方案在Windows 10上存在权限问题,已在QQ群(374992201)发布详细错误日志。完整代码已上传至Gitee(待脱敏),急需大神协助解决:

  1. ActiveX控件在Win10的兼容性问题
  2. 大文件合并时的内存溢出优化
  3. 跨浏览器进度条同步显示

明日计划:编写自动重试机制和COS上传失败后的回滚逻辑,确保20G文件传输的稳定性。


(日记结束)

附:技术栈对比表

模块原方案当前方案优化点
前端框架jQueryVue3 Composition API响应式数据管理
上传组件WebUploader基础版定制版(支持文件夹+断点)递归解析文件夹结构
后端语言PHPJSP利用Servlet处理大文件流
对象存储百度OBS腾讯云COS适配不同的分片API规范

如需完整项目或调试协助,请联系QQ群或留言获取测试账号!

导入项目

导入到Eclipse:点南查看教程
导入到IDEA:点击查看教程
springboot统一配置:点击查看教程

工程

NOSQL

NOSQL示例不需要任何配置,可以直接访问测试

创建数据表

选择对应的数据表脚本,这里以SQL为例

修改数据库连接信息

访问页面进行测试

文件存储路径

up6/upload/年/月/日/guid/filename

效果预览

文件上传

文件刷新续传

支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传

文件夹上传

支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。

下载示例

点击下载完整示例

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/3 16:16:38

Linly-Talker在抑郁症筛查中的初步对话测试

Linly-Talker在抑郁症筛查中的初步对话测试 在精神健康问题日益凸显的今天&#xff0c;一个沉默而普遍的现实是&#xff1a;许多有抑郁倾向的人从未走进心理咨询室。不是因为他们不需要帮助&#xff0c;而是因为羞耻感、资源稀缺或对“面对面倾诉”的恐惧&#xff0c;让他们选择…

作者头像 李华
网站建设 2026/2/3 22:17:15

Open-AutoGLM架构适配实战(20年专家私藏优化方案曝光)

第一章&#xff1a;Open-AutoGLM架构兼容性优化概述Open-AutoGLM作为面向多后端大模型推理的自动化适配框架&#xff0c;其核心挑战之一在于跨平台与异构硬件环境下的架构兼容性。为实现模型在不同计算设备&#xff08;如NVIDIA GPU、国产AI芯片、CPU推理引擎&#xff09;间的无…

作者头像 李华
网站建设 2026/2/3 8:38:38

Linly-Talker在火山监测预警系统的可视化表达

Linly-Talker在火山监测预警系统的可视化表达 在夏威夷基拉韦厄火山又一次喷发的清晨&#xff0c;应急指挥中心的大屏上没有出现惯常的红色警报框和滚动文字&#xff0c;而是一位神情严肃的虚拟地质专家正对着镜头说话&#xff1a;“目前熔岩流已突破南侧山脊&#xff0c;预计…

作者头像 李华
网站建设 2026/1/27 5:10:22

基于SpringBoot+Vue的植物园管理小程序的设计与实现

植物园管理小程序的课题背景随着城市化进程加快和生态环境问题日益突出&#xff0c;植物园作为生物多样性保护、科研教育及休闲观光的重要场所&#xff0c;其管理效率和服务质量受到广泛关注。传统的植物园管理多依赖人工记录和纸质档案&#xff0c;存在信息更新滞后、数据共享…

作者头像 李华
网站建设 2026/1/30 23:18:53

2025大模型时代:从神话走向现实,引领产业革命!揭秘高薪职业新趋势,抓住AI发展新机遇!

当AI不再满足于聊天&#xff0c;开始“思考”和“动手”&#xff0c;我们面对的已不是一次技术升级&#xff0c;而是一场席卷所有行业的生产力革命。“我们正处在从数字世界迈向物理世界的桥梁上。” 在北京智源人工智能研究院院长王仲远看来&#xff0c;大模型的潜力远不止于生…

作者头像 李华
网站建设 2026/2/3 10:48:08

Linly-Talker在音乐MV创作中的艺术实验

Linly-Talker在音乐MV创作中的艺术实验 在当代音乐产业中&#xff0c;视觉表达早已与声音本身同等重要。一首歌的传播力&#xff0c;往往不只取决于旋律与歌词&#xff0c;更在于它能否构建出令人沉浸的视听世界。而当AI技术悄然渗透进内容创作的底层逻辑时&#xff0c;我们正见…

作者头像 李华