当前位置: 首页 > news >正文

央企项目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

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

下载示例

点击下载完整示例

http://www.jsqmd.com/news/410878/

相关文章:

  • 2026年北京好用的智能安全帽企业推荐,实力强、售后完善的品牌有哪些 - 工业品网
  • kotlin 高阶函数用法
  • 2026广东最新天然野生沉香批发top10推荐!广州等地优质沉香生产厂家权威榜单发布,品质纯正选品指南 - 十大品牌榜
  • 盘点江苏公司认证服务,口碑排名靠谱机构大盘点 - mypinpai
  • Excel VBA对象模型
  • 互联网大厂Java求职面试实战:核心技术栈与支付金融服务场景深度解析
  • 学霸同款! 降AIGC软件 千笔·专业降AI率智能体 VS PaperRed,继续教育首选
  • 国产化CKEDITOR编辑器支持PDF文档直接粘贴上传到云存储吗?
  • Nlog 配置文件示例
  • 或许是八字手链人物传记计划外传——胡哥
  • 清单来了:9个AI论文软件深度测评,自考毕业论文写作必备工具推荐
  • 科研党收藏!继续教育论文神器 —— 千笔写作工具
  • 北京除甲醛产品多少钱,怎么选心里要有数 - 工业品网
  • 2026年美的净水器厂商口碑排名,看看哪家更靠谱 - mypinpai
  • 直接上结论:本科生专属降AIGC网站,千笔·降AI率助手 VS 万方智搜AI
  • Excelize 开源基础库发布 2.10.1 版本更新
  • 伺服PMSM中频振动抑制的相位补偿速度观测器仿真验证与离散化实现含源码
  • Nlog 示例
  • 工业4G/5G路由器制造商哪家好,适用能源领域靠谱的品牌有哪些 - myqiye
  • 2026年必看!防火涂料性能与应用,适配工程选型方法论全解析,油性防火涂料/隧道防火涂料,防火涂料订做厂家有哪些 - 品牌推荐师
  • 计算机毕业设计springboot文理校园理发店平台 基于SpringBoot的高校智慧美发预约服务平台 SpringBoot框架下的大学生理发服务数字化管理系统
  • Go Lang中JSON文件的读写操作
  • 计算机毕业设计springboot法律咨询援助平台 基于SpringBoot的在线法律服务平台设计与实现 SpringBoot框架下的数字化法律援助系统开发
  • 辽宁大学 —— 计算机科学与技术学位授权点建设年度报告
  • 聊聊2026年湖南、广西碳黑推荐厂商,哪家性价比高 - 工业设备
  • 维普AIGC检测率突然变高?2026新算法下的应对策略 - 我要发一区
  • 2026年上海有名的代理记账企业排行榜,前十名是哪些? - 工业品网
  • 收缩袋制造厂推荐哪家技术好,天津金盛昱表现出色 - myqiye
  • 2026年北京启程旅行社价格透明程度,与其他社优势对比及当地知名度排名 - mypinpai
  • 维普AIGC检测系统2026年更新了什么?最新算法解读与应对方案 - 我要发一区