news 2026/2/3 9:10:30

教育行业,JAVA如何编写网页大文件上传的示例教程?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
教育行业,JAVA如何编写网页大文件上传的示例教程?

《大文件传输系统开发手记:一个老程序员的求生指南》


一、项目背景

最近接了个"地狱级"外包:客户要我用原生JS实现20G文件夹上传/下载,还要兼容IE9!我摸着所剩无几的头发,看着100元预算,陷入了沉思…

客户核心需求

  1. 支持20G文件夹上传(含1000级子目录)
  2. 断点续传(重启电脑都不能丢进度)
  3. SM4/AES加密传输+存储
  4. 非打包下载(几万文件秒传)
  5. 兼容IE9到Chrome全系列
  6. 预算100元(买杯咖啡都不够)

二、技术选型(穷人版)

前端方案
  • 原生JS+递归算法:手动实现文件夹树遍历
  • Web Workers:防止IE9卡死
  • Blob分片:把20G切成5MB小饼干
后端方案
  • SpringBoot:白嫖的Tomcat容器
  • MySQL:记录上传进度(穷人的Redis)
  • SM4算法:用BouncyCastle库(免费!)
加密方案
// 前端AES加密(兼容IE9)functionencryptAES(data,key){// 兼容IE9的crypto-js降级方案if(typeofCryptoJS==='undefined'){alert('请安装crypto-js插件!');returndata;}returnCryptoJS.AES.encrypt(data,key).toString();}

三、核心代码实现

1. 文件夹上传(原生JS版)
// 递归扫描文件夹(IE9兼容版)functionscanFolder(entry,pathMap){if(entry.isFile){entry.file(file=>{constrelativePath=pathMap.join('/')+'/'+file.name;uploadFile(file,relativePath);// 调用分片上传});}elseif(entry.isDirectory){constdirReader=entry.createReader();dirReader.readEntries(entries=>{constnewPath=[...pathMap,entry.name];entries.forEach(e=>scanFolder(e,newPath));});}}// 初始化文件夹选择(IE9兼容)document.getElementById('folderInput').addEventListener('change',e=>{constfiles=e.target.files;if(files.length===0)return;// IE9的特殊处理if(window.FileReader&&!window.FileEntry){alert('请使用Chrome/Firefox上传文件夹!');return;}// 现代浏览器if(files[0].webkitRelativePath){constrootPath=files[0].webkitRelativePath.split('/')[0];Array.from(files).forEach(file=>{constpath=file.webkitRelativePath.replace(rootPath,'');uploadFile(file,path);});}// 通过input[webkitdirectory]选择elseif(e.target.webkitEntries){Array.from(e.target.webkitEntries).forEach(entry=>{scanFolder(entry,[]);});}});
2. 分片上传(断点续传)
// 上传文件分片asyncfunctionuploadChunk(file,chunkIndex,totalChunks,filePath,fileId){constchunkSize=5*1024*1024;// 5MBconststart=chunkIndex*chunkSize;constend=Math.min(file.size,start+chunkSize);constchunk=file.slice(start,end);// 加密分片(SM4)constencrypted=awaitencryptSM4(chunk,'1234567890abcdef');// 实际应从后端获取密钥returnfetch('/api/upload',{method:'POST',body:encrypted,headers:{'X-File-ID':fileId,'X-Chunk-Index':chunkIndex,'X-Total-Chunks':totalChunks,'X-File-Path':filePath}}).then(res=>res.json());}// 进度持久化(localStorage+IndexedDB双备份)functionsaveProgress(fileId,progress){try{// IE9兼容方案if(window.localStorage){localStorage.setItem(`progress_${fileId}`,JSON.stringify(progress));}// 现代浏览器用IndexedDBif(window.indexedDB){constrequest=indexedDB.open('FileProgressDB',1);request.onsuccess=()=>{constdb=request.result;consttx=db.transaction('progress','readwrite');conststore=tx.objectStore('progress');store.put(progress,fileId);};}}catch(e){console.error('进度保存失败:',e);}}
3. SpringBoot后端(穷人版)
@RestController@RequestMapping("/api")publicclassFileController{@Value("${file.storage.path}")privateStringstoragePath;// 分片上传接口@PostMapping("/upload")publicResponseEntityuploadChunk(@RequestParam("file")MultipartFilefile,@RequestHeader("X-File-ID")StringfileId,@RequestHeader("X-Chunk-Index")intchunkIndex,@RequestHeader("X-Total-Chunks")inttotalChunks,@RequestHeader("X-File-Path")StringfilePath){try{// 解密文件(SM4)byte[]decrypted=decryptSM4(file.getBytes(),"1234567890abcdef");// 保存分片StringchunkPath=storagePath+"/"+fileId+"/chunks/"+chunkIndex;Files.createDirectories(Paths.get(chunkPath).getParent());Files.write(Paths.get(chunkPath),decrypted);// 更新进度到MySQLupdateProgress(fileId,chunkIndex,totalChunks,filePath);returnResponseEntity.ok().body(Map.of("success",true));}catch(Exceptione){returnResponseEntity.status(500).body(Map.of("error",e.getMessage()));}}// 合并文件(伪代码)@GetMapping("/merge")publicResponseEntitymergeFile(@RequestParamStringfileId){// 1. 从MySQL查询所有分片信息// 2. 按顺序合并到最终文件// 3. 删除分片目录// 4. 返回下载URLreturnResponseEntity.ok().body(Map.of("url","/download/"+fileId));}}

四、兼容性黑科技

1. IE9兼容方案
2. 文件夹上传降级方案
// 如果浏览器不支持文件夹上传,提示用户压缩成ZIPfunctioncheckFolderSupport(){if(!window.File&&!window.FileReader&&!window.FileList&&!window.Blob){alert('您的浏览器太古老了!请:\n1. 使用Chrome/Firefox\n2. 或把文件夹压缩成ZIP上传');}}

五、部署指南(白嫖版)

  1. 服务器配置

    • 买台1核2G的云服务器(阿里云学生机9.9元/月)
    • 安装Tomcat + MySQL
  2. 编译打包

    # 前端打包npmrun build# 后端打包mvn clean package# 手动复制dist目录到Tomcat的webappscp-r dist/* /var/lib/tomcat9/webapps/ROOT/
  3. MySQL初始化

CREATETABLEfile_progress(idVARCHAR(64)PRIMARYKEY,file_pathVARCHAR(512)NOTNULL,total_chunksINTNOTNULL,received_chunksINTDEFAULT0,last_updateTIMESTAMPDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP);

六、项目总结

  1. 成果:用100元预算实现了20G文件夹上传!
  2. 代价:头发又少了100根…
  3. 建议:下次接单前先看牙医(防止气到咬碎后槽牙)

最终解决方案

  • 前端代码:GitHub链接
  • 后端代码:附在邮件压缩包里
  • 交流群:374992201(加群领红包!)

温馨提示:本项目仅供学习交流,如需商用请自行购买商业授权(虽然我根本没卖…)

导入项目

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

工程

NOSQL

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

创建数据表

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

修改数据库连接信息

访问页面进行测试

文件存储路径

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

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

下载示例

点击下载完整示例

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

5.3 PPT制作效率爆炸提升:Gamma助力非设计专业也能做出精美演示文稿

5.3 PPT制作效率爆炸提升:Gamma助力非设计专业也能做出精美演示文稿 在职场沟通和商务展示中,演示文稿(PPT)是传递信息、展示观点和影响决策的重要工具。然而,对于大多数非设计专业的职场人士来说,制作一份既美观又专业的PPT往往是一项耗时耗力的任务。从内容组织到视觉设…

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

支配树算法原理及鸿蒙工具实践

本文介绍了支配树(Dominator Tree)算法在鸿蒙系统 ArkTS 内存分析工具中的应用。为应对淘宝 App 鸿蒙版因内存溢出导致的 Crash 问题,作者构建了一套从客户端采集内存快照、服务端自动分析的工具链。文中对比了多种支配树构建算法&#xff08…

作者头像 李华
网站建设 2026/2/3 2:31:42

Deepoc具身模型开发板:让智能轮椅成为“懂你“的贴心伙伴

引言:从代步工具到智能伴侣的跨越在传统认知中,轮椅只是行动不便者的代步工具,功能单一、操作复杂、缺乏智能。老人需要反复学习才能掌握操作,残障人士在复杂环境中仍需要他人协助,护理人员工作强度大且效率低下。Deep…

作者头像 李华