news 2026/1/30 5:24:38

SpringMVC大文件上传的加密传输经验总结交流

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringMVC大文件上传的加密传输经验总结交流

大文件传输系统开源组件调研与自研方案探索

作为一名参与政府招投标项目的开发人员,目前正面临着大文件传输功能开发的挑战。项目要求支持 20G 左右文件的传输,涵盖文件和文件夹的上传与下载,且文件夹传输需保留层级结构。同时,要兼容主流浏览器以及信创国产浏览器(如龙芯浏览器、红莲花浏览器、奇安信安全浏览器),支持信创国产化操作系统(统信 UOS、中标麒麟、银河麒麟),数据库方面需兼容主流产品(SQL Server、MySQL、Oracle)和国产化产品(达梦、人大金仓)。后端采用 SpringBoot,前端使用 vue2 - cli 框架。

现有开源组件调研

在项目初期,我对市场上的开源组件进行了调研。百度开源的大文件上传组件 WebUploader 曾进入我的视野,但经过深入了解发现,该组件已经停更,这意味着后续使用过程中遇到问题将无法获得技术支持。考虑到政府和军工单位项目对稳定性和安全性的高要求,没有技术支持的组件存在较大风险,公司领导也不太认可使用。

除了 WebUploader,我还调研了其他一些开源组件,但它们普遍存在没有技术支持的问题。在项目开发过程中,遇到问题无法及时联系到作者解决,这可能会导致项目进度延迟,甚至影响项目的整体质量。因此,这些开源组件都无法满足我们的需求。

采购源代码自研的必要性

鉴于开源组件的局限性,公司领导决定采购产品源代码,由公司研发部门负责开发。这一决策主要基于以下几点考虑:

  1. 项目数量多:公司每年约 2000 + 个项目,如果采用单套授权的方式,成本高且管理麻烦。采购源代码可以一次性投入,降低长期成本。
  2. 客户要求:客户主要是政府和军工单位,对产品的源代码有需求,以便进行安全审计和定制化开发。
  3. 自研需求:产品部门有自研的需求,采购源代码可以为后续的自主研发提供基础,提升公司的技术实力和竞争力。

自研方案探索

前端实现

前端使用 vue2 - cli 框架,为了实现大文件上传和文件夹上传功能,可以利用 HTML5 的 File API 和 Drag and Drop API。以下是一个简单的文件选择和上传的代码示例:

export default { data() { return { selectedFiles: [] }; }, methods: { handleFileChange(event) { const files = event.target.files; this.selectedFiles = Array.from(files); }, uploadFiles() { const formData = new FormData(); this.selectedFiles.forEach(file => { formData.append('files', file); }); // 这里可以添加文件夹层级结构信息到 formData 中 fetch('/api/upload', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { console.log('上传成功', data); }) .catch(error => { console.error('上传失败', error); }); } } };

后端实现

后端使用 SpringBoot 框架,需要处理大文件的接收和存储。可以使用分片上传的方式,将大文件分割成多个小文件进行上传,然后在服务器端进行合并。以下是一个简单的 SpringBoot 控制器代码示例:

importorg.springframework.web.bind.annotation.*;importorg.springframework.web.multipart.MultipartFile;importjava.io.File;importjava.io.IOException;importjava.nio.file.Files;importjava.nio.file.Path;importjava.nio.file.Paths;importjava.util.List;@RestController@RequestMapping("/api")publicclassFileUploadController{privatestaticfinalStringUPLOAD_DIR="/path/to/upload/directory";@PostMapping("/upload")publicStringuploadFiles(@RequestParam("files")Listfiles){for(MultipartFilefile:files){try{// 这里可以处理文件夹层级结构信息byte[]bytes=file.getBytes();Pathpath=Paths.get(UPLOAD_DIR+File.separator+file.getOriginalFilename());Files.write(path,bytes);}catch(IOExceptione){e.printStackTrace();return"上传失败";}}return"上传成功";}}

分片上传与合并

为了实现大文件的分片上传和合并,可以在前端将文件分割成多个分片,并为每个分片添加唯一的标识符。后端接收到分片后,将其存储在临时目录中,等所有分片都上传完成后,再进行合并。以下是一个简单的分片上传和合并的思路:

  1. 前端分片
functionsliceFile(file,chunkSize){constchunks=[];letstart=0;while(start<file.size){constend=Math.min(start+chunkSize,file.size);chunks.push(file.slice(start,end));start=end;}returnchunks;}functionuploadChunks(file,chunkSize){constchunks=sliceFile(file,chunkSize);constpromises=[];chunks.forEach((chunk,index)=>{constformData=newFormData();formData.append('file',chunk);formData.append('fileName',file.name);formData.append('chunkIndex',index);formData.append('totalChunks',chunks.length);promises.push(fetch('/api/uploadChunk',{method:'POST',body:formData}));});Promise.all(promises).then(()=>{// 所有分片上传完成后,通知后端合并fetch('/api/mergeChunks',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({fileName:file.name})}).then(response=>response.json()).then(data=>{console.log('合并成功',data);});});}
  1. 后端接收分片和合并
importorg.springframework.web.bind.annotation.*;importorg.springframework.web.multipart.MultipartFile;importjava.io.File;importjava.io.IOException;importjava.nio.file.Files;importjava.nio.file.Path;importjava.nio.file.Paths;importjava.util.HashMap;importjava.util.Map;@RestController@RequestMapping("/api")publicclassChunkUploadController{privatestaticfinalStringTEMP_DIR="/path/to/temp/directory";privatestaticfinalMapchunkCountMap=newHashMap<>();@PostMapping("/uploadChunk")publicStringuploadChunk(@RequestParam("file")MultipartFilefile,@RequestParam("fileName")StringfileName,@RequestParam("chunkIndex")intchunkIndex,@RequestParam("totalChunks")inttotalChunks){try{PathtempPath=Paths.get(TEMP_DIR+File.separator+fileName+"_"+chunkIndex);Files.write(tempPath,file.getBytes());// 记录已上传的分片数量chunkCountMap.put(fileName,chunkCountMap.getOrDefault(fileName,0)+1);return"分片上传成功";}catch(IOExceptione){e.printStackTrace();return"分片上传失败";}}@PostMapping("/mergeChunks")publicStringmergeChunks(@RequestBodyMaprequestBody){StringfileName=requestBody.get("fileName");inttotalChunks=chunkCountMap.getOrDefault(fileName,0);if(totalChunks==0){return"没有找到分片信息";}try{PathfinalPath=Paths.get("/path/to/final/directory"+File.separator+fileName);// 这里可以使用更高效的合并方式,如使用 RandomAccessFilefor(inti=0;i<totalChunks;i++){PathchunkPath=Paths.get(TEMP_DIR+File.separator+fileName+"_"+i);byte[]bytes=Files.readAllBytes(chunkPath);Files.write(finalPath,bytes,java.nio.file.StandardOpenOption.APPEND);Files.delete(chunkPath);}chunkCountMap.remove(fileName);return"合并成功";}catch(IOExceptione){e.printStackTrace();return"合并失败";}}}

总结

目前,我正在积极探索适合项目的大文件传输解决方案。采购源代码自研虽然需要投入一定的时间和精力,但从长远来看,可以满足公司的项目需求和客户要求,提升公司的技术实力和竞争力。在后续的开发过程中,我将继续完善前端和后端的代码,实现大文件传输的完整功能,并进行充分的测试,确保系统的稳定性和可靠性。同时,我也会关注市场上是否有更合适的开源组件出现,以便及时调整开发方案。

SQL示例

创建数据库

配置数据库连接

自动下载maven依赖

启动项目

启动成功

访问及测试

默认页面接口定义

在浏览器中访问

数据表中的数据

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

批量下载

支持文件批量下载

下载续传

文件下载支持离线保存进度信息,刷新页面,关闭页面,重启系统均不会丢失进度信息。

文件夹下载

支持下载文件夹,并保留层级结构,不打包,不占用服务器资源。

示例下载

下载完整示例

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

基于YOLOv10的麻将识别检测系统(YOLOv10深度学习+YOLO数据集+UI界面+Python项目源码+模型)

一、项目介绍 摘要 本项目基于YOLOv10目标检测算法开发了一套专业的麻将牌识别检测系统&#xff0c;旨在实现对各类麻将牌的高精度识别与定位。系统能够准确识别42种不同类型的麻将牌&#xff0c;包括万、条、筒、风牌和箭牌等常见麻将类别。项目采用深度学习技术&#xff0c…

作者头像 李华
网站建设 2026/1/29 22:53:07

海尔冰箱屏幕互动:内置HeyGem数字人提供菜谱推荐

海尔冰箱屏幕互动&#xff1a;内置HeyGem数字人提供菜谱推荐 在厨房里打开冰箱门&#xff0c;屏幕上一位面带微笑的虚拟营养师立刻迎上来&#xff1a;“您有鸡蛋和番茄&#xff0c;今天要不要试试酸甜开胃的番茄炒蛋&#xff1f;”这不是科幻电影的桥段&#xff0c;而是搭载了H…

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

比亚迪新能源车说明书数字化:HeyGem生成驾驶指南视频

比亚迪新能源车说明书数字化&#xff1a;HeyGem生成驾驶指南视频 在智能汽车时代&#xff0c;用户打开一辆新车的第一件事是什么&#xff1f;不是试驾&#xff0c;也不是调座椅——而是翻说明书。但当面对厚厚一叠PDF或密密麻麻的文字手册时&#xff0c;大多数人只能望而却步。…

作者头像 李华
网站建设 2026/1/25 2:04:57

【Linux命令大全】003.文档编辑之fold命令(实操篇)

【Linux命令大全】003.文档编辑之fold命令&#xff08;实操篇&#xff09; ✨ 本文为Linux系统文档编辑与文本处理命令的全面汇总与深度优化&#xff0c;结合图标、结构化排版与实用技巧&#xff0c;专为高级用户和系统管理员打造。 (关注不迷路哈&#xff01;&#xff01;&…

作者头像 李华
网站建设 2026/1/25 2:04:55

图像识别API接入难题,如何用PHP在1小时内搞定?

第一章&#xff1a;图像识别API接入难题&#xff0c;如何用PHP在1小时内搞定&#xff1f;在现代Web开发中&#xff0c;图像识别能力正逐渐成为应用标配。无论是内容审核、智能标签还是自动化分类&#xff0c;接入图像识别API已成为提升产品智能化的关键一步。然而&#xff0c;许…

作者头像 李华