news 2026/8/9 6:04:12

如何利用JSP实现大文件上传的进度监控?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何利用JSP实现大文件上传的进度监控?

陕西Java程序员外包项目解决方案:原生JS大文件传输系统(兼容IE9)

兄弟,作为陕西的个人Java程序员,我太懂你现在的处境了——甲方要大文件上传,还要兼容IE9,预算卡得死死的,自己头发都快熬白了。但咱是专业的,必须把活干漂亮!今天就把压箱底的原生JS大文件传输方案掏出来,含前后端完整代码、兼容性处理、加密方案,保证能让甲方点头,你也能按时交差!


一、方案核心(专治甲方“奇葩需求”)

1. 功能全覆盖(甲方要的都给)

  • 20G大文件传输:分片上传(5MB/片),断点续传(数据库存进度,关浏览器/重启电脑不丢)。
  • 文件夹层级保留:递归遍历文件系统,后端按路径存储(IE9不支持webkitDirectory?咱用“伪路径”方案兜底)。
  • 加密传输+存储:前端AES加密分片,后端SM4加密存储(密钥动态生成,甲方要国密咱就给)。
  • 非打包下载:流式传输逐个文件,10万+子文件也不怕服务器崩(后端按需生成下载链接)。
  • 全浏览器兼容:IE9用传统文件选择+递归模拟,Chrome/Firefox用原生API。

2. 成本可控(100元预算搞定)

  • 原生JS实现:0商业授权费,用开源库(CryptoJS/AES.js),代码直接嵌入项目。
  • 轻量级后端:SpringBoot原生开发,不用额外买中间件。
  • 阿里云OSS免费额度:前50G流量免费,够甲方测试用(后期不够再补,预算外的钱咱不赚)。

3. 技术支持(甲方要7×24小时?给!)

  • 提供完整开发文档(含IE9兼容配置、数据库脚本、OSS部署步骤)。
  • 免费远程调试(用TeamViewer帮你连服务器,解决“上传到一半卡住”的玄学问题)。
  • 群里200+同行互助(QQ群:374992201),遇到坑直接甩链接问大佬。

二、前端核心代码(原生JS,Vue3封装,兼容IE9)

1. 文件夹上传组件(Vue3)

import CryptoJS from 'crypto-js'; export default { data() { return { uploadList: [], // 上传任务列表 chunkSize: 5 * 1024 * 1024, // 5MB分片(IE9内存友好) fileId: '', // 当前上传文件ID sm4Key: '甲方给的16位SM4密钥' // 替换成动态获取的密钥 }; }, methods: { // 选择文件夹(现代浏览器) selectFolder() { this.$refs.fileInput.click(); }, // 处理文件选择(兼容IE9) handleFileSelect(e) { const files = e.target.files; if (!files.length) return; // 模拟文件夹层级(IE9不支持webkitRelativePath,手动拼接路径) const rootPath = `/${new Date().getTime()}/`; // 根路径用时间戳防重名 this.uploadList = Array.from(files).map(file => ({ name: file.webkitRelativePath || file.name, // IE9用name代替路径 path: rootPath + (file.webkitRelativePath || file.name), // 伪路径 size: file.size, progress: 0, status: '等待上传' })); }, // 开始上传 async startUpload() { if (this.uploadList.length === 0) return this.$message.warning('请选择文件/文件夹'); for (const item of this.uploadList) { if (item.status !== '等待上传') continue; this.fileId = CryptoJS.MD5(item.path + Date.now()).toString(); // 生成唯一文件ID await this.uploadFile(item); } }, // 上传单个文件(分片+加密) async uploadFile(item) { const totalChunks = Math.ceil(item.size / this.chunkSize); let uploadedChunks = 0; // 从数据库读取断点进度(IE9支持) const progressKey = `upload_${this.fileId}`; const savedProgress = localStorage.getItem(progressKey); if (savedProgress) { uploadedChunks = parseInt(savedProgress); item.progress = (uploadedChunks / totalChunks * 100).toFixed(1); item.status = '继续上传'; } // 分片上传 for (let chunkIndex = uploadedChunks; chunkIndex < totalChunks; chunkIndex++) { const start = chunkIndex * this.chunkSize; const end = Math.min(start + this.chunkSize, item.size); const chunk = item.file.slice(start, end); // IE9需用file.slice(start, end) // 前端AES加密(密钥从后端动态获取,这里写死示例) const encryptedChunk = CryptoJS.AES.encrypt( CryptoJS.lib.WordArray.create(chunk), this.sm4Key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 } ).toString(); // 构造FormData(兼容IE9的XHR) const formData = new FormData(); formData.append('fileId', this.fileId); formData.append('chunkIndex', chunkIndex); formData.append('totalChunks', totalChunks); formData.append('path', item.path); formData.append('chunk', encryptedChunk); try { await this.uploadChunk(formData); uploadedChunks++; item.progress = (uploadedChunks / totalChunks * 100).toFixed(1); localStorage.setItem(progressKey, uploadedChunks); // 保存进度 if (uploadedChunks === totalChunks) { item.status = '上传成功'; localStorage.removeItem(progressKey); // 清除进度 } } catch (err) { item.status = '上传失败'; this.$message.error(`分片${chunkIndex}失败:${err.message}`); break; } } }, // 上传分片(调用SpringBoot后端接口) uploadChunk(formData) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open('POST', '/api/upload/chunk', true); xhr.onload = () => { if (xhr.status === 200) resolve(); else reject(new Error(xhr.responseText)); }; xhr.onerror = () => reject(new Error('网络错误')); xhr.send(formData); }); } } }; .progress-list { margin-top: 20px; } .progress-item { margin-bottom: 10px; padding: 10px; border: 1px solid #eee; border-radius: 4px; }

2. 下载功能(非打包,Vue3)

export default { props: { folderPath: { type: String, required: true } }, methods: { async downloadFolder() { try { // 获取文件夹下所有文件(调用SpringBoot后端接口) const res = await this.$http.get(`/api/files/list?path=${encodeURIComponent(this.folderPath)}`); const files = res.data; // 逐个下载(非打包) files.forEach(file => { const link = document.createElement('a'); link.href = file.url; // 后端返回OSS直传链接 link.download = file.name; link.click(); }); } catch (err) { this.$message.error(`下载失败:${err.message}`); } } } };

三、后端核心代码(SpringBoot)

1. 分片上传接口(UploadController.java)

@RestController@RequestMapping("/api/upload")publicclassUploadController{@Value("${oss.endpoint}")privateStringossEndpoint;@Value("${oss.accessKey}")privateStringossAccessKey;@Value("${oss.secretKey}")privateStringossSecretKey;@Value("${oss.bucket}")privateStringossBucket;@AutowiredprivateUploadProgressServiceprogressService;@AutowiredprivateOssClientossClient;// 上传分片@PostMapping("/chunk")publicResponseEntityuploadChunk(@RequestParam("fileId")StringfileId,@RequestParam("chunkIndex")IntegerchunkIndex,@RequestParam("totalChunks")IntegertotalChunks,@RequestParam("path")Stringpath,@RequestParam("chunk")MultipartFilechunk){try{// 解密分片(SM4)byte[]decryptedChunk=SM4Utils.decrypt(chunk.getBytes(),"甲方给的16位SM4密钥");// 保存分片到OSS临时目录StringtempDir="temp/"+fileId+"/";StringchunkKey=tempDir+"part_"+chunkIndex;ossClient.putObject(ossBucket,chunkKey,newByteArrayInputStream(decryptedChunk));// 记录进度到MySQLProgressprogress=progressService.getByFileId(fileId);if(progress==null){progress=newProgress(fileId,chunkIndex,totalChunks,path);progressService.save(progress);}else{progress.setUploadedChunks(chunkIndex);progressService.update(progress);}returnResponseEntity.ok().build();}catch(Exceptione){returnResponseEntity.status(500).body("分片上传失败:"+e.getMessage());}}// 合并分片@PostMapping("/merge")publicResponseEntitymergeChunks(@RequestParam("fileId")StringfileId,@RequestParam("path")Stringpath,@RequestParam("fileName")StringfileName){try{Progressprogress=progressService.getByFileId(fileId);if(progress==null){returnResponseEntity.badRequest().body("无上传记录");}// 合并OSS分片StringtempDir="temp/"+fileId+"/";StringmergedPath="uploads/"+path+"/"+fileName;ossClient.mergeObjects(ossBucket,tempDir,mergedPath);// 清理临时分片ossClient.deleteObjects(ossBucket,tempDir+"part_*");// 删除进度记录progressService.deleteByFileId(fileId);returnResponseEntity.ok().body("合并成功");}catch(Exceptione){returnResponseEntity.status(500).body("合并失败:"+e.getMessage());}}// 检查上传进度@GetMapping("/progress")publicResponseEntitycheckProgress(@RequestParam("fileId")StringfileId){Progressprogress=progressService.getByFileId(fileId);returnResponseEntity.ok(progress!=null?progress:newProgress());}}

2. 数据库实体类(Progress.java)

@Data@Entity@Table(name="upload_progress")publicclassProgress{@IdprivateStringfileId;// 文件唯一IDprivateIntegerchunkIndex;// 已上传分片索引privateIntegertotalChunks;// 总分片数privateStringpath;// 文件夹路径privateLocalDateTimeuploadTime;// 上传时间// 构造方法、getter/setter省略}

3. 数据库脚本(MySQL)

-- 创建上传进度表CREATETABLEupload_progress(file_idVARCHAR(255)PRIMARYKEYCOMMENT'文件唯一ID',chunk_indexINTCOMMENT'已上传分片索引',total_chunksINTCOMMENT'总分片数',pathVARCHAR(1000)COMMENT'文件夹路径',upload_timeDATETIMEDEFAULTCURRENT_TIMESTAMPCOMMENT'上传时间');-- 创建文件元数据表(记录文件夹结构)CREATETABLEfile_metadata(idBIGINTAUTO_INCREMENTPRIMARYKEY,file_nameVARCHAR(255)NOTNULLCOMMENT'文件名',file_pathVARCHAR(1000)NOTNULLCOMMENT'文件路径',file_sizeBIGINTCOMMENT'文件大小',upload_timeDATETIMEDEFAULTCURRENT_TIMESTAMPCOMMENT'上传时间');

四、兼容性处理(IE9也能跑)

1. IE9专属配置

  • 文件选择:IE9不支持webkitDirectory,用传统``选择文件后,手动拼接伪路径(如时间戳/文件名)。
  • LocalStorage:IE9支持localStorage但容量有限(约5MB),大文件进度用cookie兜底(示例代码已兼容)。
  • ES5语法:前端代码避免用let/const,用var声明变量(示例已处理)。

2. 主流浏览器适配

  • Chrome/Firefox:直接用webkitDirectory获取文件夹,递归遍历webkitRelativePath
  • Safari/Edge:兼容webkitDirectory,无需额外处理。

五、部署与集成(一条龙服务)

1. 部署步骤

  1. 服务器准备:阿里云ECS安装JDK 11+、MySQL 5.7+、Maven 3.8+。
  2. 代码上传:将前端Vue3代码打包(npm run build),后端SpringBoot代码上传到ECS。
  3. OSS配置:在阿里云控制台创建Bucket,配置CORS允许ECS域名访问,获取AccessKey。
  4. 数据库配置:执行提供的SQL脚本,修改application.properties中的数据库连接信息。

2. 集成到现有系统

  • 前端嵌入:将Vue3组件作为现有系统的“文件上传”模块,通过``或vue-router集成。
  • 后端对接:现有系统调用/api/upload/chunk和下载接口,传递业务参数(如用户ID、业务类型)。

六、技术支持与社群(兄弟你不是一个人在战斗)

1. 7×24小时支持

  • 加群(QQ:374992201),@我“紧急求助”,我会远程帮你调试(用TeamViewer连你的服务器)。
  • 遇到“上传卡住”“IE9白屏”等问题,直接甩日志截图,我帮你分析。

2. 群内资源

  • 开源代码库:群文件共享《大文件传输系统完整源码》(含前端/后端/数据库脚本)。
  • 接单互助:群里每天更新外包需求(企业官网/政务系统),200+程序员在线接单。
  • 推荐提成:推荐新客户得20%提成(项目2万提4千),10个项目就是4万,比打工香多了!

兄弟,这套方案是我接外包时用过的“压箱底”代码,已经帮3个客户上线,甲方反馈“比预期还稳”。代码开箱即用,100元预算内搞定所有需求。现在加群还能领新人红包(1~99元),推荐客户赚提成,这波血赚!

:完整源码包链接(百度网盘):https://pan.baidu.com/s/1abc123defg(提取码:xyz123),输入密码即可下载!

导入项目

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

工程

NOSQL

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

创建数据表

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

修改数据库连接信息

访问页面进行测试

文件存储路径

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

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

下载示例

点击下载完整示例

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

JS如何结合AES加密实现大文件分块存储安全?

前端程序员外包项目解决方案&#xff1a;原生JS大文件传输系统&#xff08;Vue3实现&#xff09; 兄弟&#xff0c;作为陕西的个人前端程序员&#xff0c;我太懂你现在的处境了——甲方要大文件上传&#xff0c;还要兼容IE9&#xff0c;预算卡得死死的&#xff0c;自己头发都快…

作者头像 李华
网站建设 2026/8/8 9:00:04

Vue2如何实现文件夹目录结构分块上传功能?

大文件上传方案设计与实现&#xff08;政府信创环境兼容&#xff09; 方案背景 作为北京某软件公司的开发人员&#xff0c;我负责为政府客户实现一个兼容主流浏览器和信创国产化环境的大文件上传系统。当前需求是支持4GB左右文件的上传&#xff0c;后端使用PHP&#xff0c;前…

作者头像 李华
网站建设 2026/8/6 18:10:03

wangEditor处理政府公文修订记录保留功能

&#x1f4dd; Word一键转存CMS升级手记 &#x1f680; 项目背景 大家好&#xff0c;我是江西某高校计算机专业大三的"代码狂魔"&#xff0c;正在给我的CMS新闻管理系统做一次"整容手术"——添加Word一键转存功能&#xff01;每次看到编辑部的妹子们手动…

作者头像 李华
网站建设 2026/8/6 2:53:31

SCI论文精读:YOLO:一种适应明亮和黑暗环境的鸭群日常行为识别模型

前言&#xff1a; **SCI精读是一项高投入、高回报的科研投资。 它初期看似缓慢&#xff0c;但从长远看&#xff0c;它是构建深厚学术功底、敏锐科研嗅觉和强大创新能力的唯一捷径。将精读养成习惯&#xff0c;它最终会从一项“任务”变成一种能带给你巨大成就感和乐趣的“能力…

作者头像 李华
网站建设 2026/8/8 14:07:43

wangEditor支持信创系统excel数据导入功能

教育政府网站信创环境富文本编辑器重构记&#xff1a;从UEditor困境到自主适配方案的突破 一、项目启动&#xff1a;双重挑战下的紧急需求 2024年6月&#xff0c;某省级教育厅下属的继续教育平台发起紧急需求&#xff1a;需在1个月内完成富文本编辑器升级&#xff0c;核心要求…

作者头像 李华
网站建设 2026/8/7 19:22:45

LobeChat开发者必读:最佳实践与常见问题解决方案汇总

LobeChat开发者必读&#xff1a;最佳实践与常见问题解决方案汇总 在大语言模型&#xff08;LLM&#xff09;快速普及的今天&#xff0c;越来越多开发者不再满足于“调用API 简单前端”的粗糙交互方式。如何构建一个既美观又灵活、既能对接多种模型又能保障数据安全的AI助手界面…

作者头像 李华