SpringMVC如何处理文件夹上传及目录结构?

湖南某软件公司前端工程师大文件传输方案(20G+兼容IE8)

一、需求分析与技术选型
  1. 核心需求拆解

    • 文件传输:
      • 单文件20G+分片上传/下载
      • 文件夹递归结构保留(含空文件夹)
      • 传输中断续传(MD5校验)
    • 安全要求:
      • 传输加密:SM4/AES前端可配置
      • 存储加密:后端透明加密(数据库字段级)
    • 兼容性:
      • 浏览器:IE8+、Chrome 45+、Firefox 52+
      • 操作系统:Windows 7/10/11、macOS 10.12+、Linux(Ubuntu 18.04+)
  2. 技术选型评估

    方案优势缺陷适配成本
    自研方案完全可控,兼容性可深度定制开发周期长(预估3个月)
    Plupload + 改造成熟分片上传,IE8兼容文件夹支持弱,无SM4支持
    最终选择Resumable.js + WebSocket需解决IE8兼容性问题中高
    • 关键决策点:
      • 放弃Flash方案(IE8需NPAPI支持,现代浏览器已禁用)
      • 采用File API+Blob+FormData组合实现分片
      • 使用WebSocket替代XHR实现进度实时推送(IE8降级为轮询)
二、前端实现方案(Vue3 + TypeScript)
  1. 核心架构设计
// src/core/uploader/index.tsinterfaceUploadConfig{chunkSize:number;// 分片大小(默认5MB)encryptType:'SM4'|'AES';// 加密算法parallel:number;// 并发数(默认3)retryTimes:number;// 重试次数(默认3)}classBigFileUploader{privateconfig:UploadConfig;privatefileTree:FileNode[];// 文件夹树结构privatesocket?:WebSocket;constructor(config:Partial={}){this.config={chunkSize:5*1024*1024,encryptType:'AES',parallel:3,retryTimes:3,...config};}// 初始化上传(兼容IE8)publicasyncinitUpload(fileInput:HTMLInputElement){constfiles=Array.from(fileInput.files||[]);if(files.length===0)return;// 构建文件树(保留文件夹结构)this.fileTree=this.buildFileTree(files);// 加密策略选择constencryptFn=this.config.encryptType==='SM4'?this.sm4Encrypt:this.aesEncrypt;// 分片上传主逻辑for(constfileNodeofthis.fileTree){awaitthis.uploadNode(fileNode,encryptFn);}}// 文件夹递归处理(IE8兼容)privatebuildFileTree(files:File[]):FileNode[]{// 实现略:通过webkitRelativePath或自定义路径解析// 关键点:处理IE8的File API缺失问题}}
  1. IE8兼容性实现
// src/utils/ie8-polyfill.js// 1. Blob切片模拟(IE8无Blob.slice)if(!window.Blob.prototype.slice){window.Blob.prototype.slice=function(start,end){constblob=this;constbb=newwindow.BlobBuilder();// 模拟切片逻辑(性能较差)// ...returnbb.getBlob();};}// 2. WebSocket降级方案exportfunctioncreateSocket(url:string){if(window.WebSocket){returnnewWebSocket(url);}else{// IE8使用ActiveXObject(需用户安装特定控件)try{returnnewActiveXObject("Microsoft.XMLHTTP");}catch(e){console.error("WebSocket not supported");returnnull;}}}
  1. 分片加密上传组件
import { defineComponent, ref } from 'vue'; import BigFileUploader from '@/core/uploader'; import { sm4Encrypt, aesEncrypt } from '@/utils/crypto'; export default defineComponent({ setup() { const fileInput = ref<HTMLInputElement | null>(null); const progress = ref(0); const encryptType = ref<'AES' | 'SM4'>('AES'); const uploader = new BigFileUploader({ encryptType: encryptType.value }); const handleFileChange = () => { if (!fileInput.value?.files) return; uploader.initUpload(fileInput.value); }; const updateConfig = () => { uploader.config.encryptType = encryptType.value; }; return { fileInput, progress, encryptType, handleFileChange, updateConfig }; } });
三、后端SpringBoot实现关键点
  1. 分片接收接口
// src/main/java/com/example/controller/UploadController.java@RestController@RequestMapping("/api/upload")publicclassUploadController{@PostMapping("/chunk")publicResponseEntityuploadChunk(@RequestParam("file")MultipartFilefile,@RequestParam("chunkNumber")intchunkNumber,@RequestParam("totalChunks")inttotalChunks,@RequestParam("fileId")StringfileId,@RequestParam("encryptType")StringencryptType){try{// 1. 解密分片(根据配置调用SM4/AES解密)byte[]decryptedData=CryptoUtil.decrypt(file.getBytes(),encryptType,fileId// 使用fileId作为IV);// 2. 临时存储分片PathtempDir=Paths.get("/tmp/uploads/"+fileId);Files.createDirectories(tempDir);PathchunkPath=tempDir.resolve("chunk_"+chunkNumber);Files.write(chunkPath,decryptedData);// 3. 检查是否所有分片已上传if(chunkNumber==totalChunks){mergeChunks(fileId,totalChunks);}returnResponseEntity.ok("Chunk uploaded successfully");}catch(Exceptione){returnResponseEntity.status(500).body(e.getMessage());}}privatevoidmergeChunks(StringfileId,inttotalChunks)throwsIOException{// 实现分片合并逻辑// ...}}
  1. 加密存储实现
// src/main/java/com/example/util/CryptoUtil.javapublicclassCryptoUtil{privatestaticfinalStringSM4_KEY="your-sm4-key-16bytes";privatestaticfinalStringAES_KEY="your-aes-key-16bytes";publicstaticbyte[]decrypt(byte[]data,Stringalgorithm,Stringiv){try{if("SM4".equalsIgnoreCase(algorithm)){returnsm4Decrypt(data,iv);}else{returnaesDecrypt(data,iv);}}catch(Exceptione){thrownewRuntimeException("Decrypt failed",e);}}privatestaticbyte[]sm4Decrypt(byte[]data,Stringiv)throwsException{// 使用BouncyCastle实现SM4// ...}privatestaticbyte[]aesDecrypt(byte[]data,Stringiv)throwsException{Ciphercipher=Cipher.getInstance("AES/CBC/PKCS5Padding");SecretKeySpeckeySpec=newSecretKeySpec(AES_KEY.getBytes(),"AES");IvParameterSpecivSpec=newIvParameterSpec(iv.getBytes());cipher.init(Cipher.DECRYPT_MODE,keySpec,ivSpec);returncipher.doFinal(data);}}
四、关键问题解决方案
  1. IE8文件夹上传问题

    • 解决方案:
      if (window.navigator.userAgent.indexOf("MSIE 8") > -1) { document.querySelector('input[type="file"]').removeAttribute('webkitdirectory'); alert('IE8不支持文件夹上传,请手动选择文件'); }
  2. 大文件内存优化

    // 使用流式处理避免内存溢出privateasyncuploadLargeFile(file:File,encryptFn:Function){constchunkSize=this.config.chunkSize;consttotalChunks=Math.ceil(file.size/chunkSize);for(leti=0;i<totalChunks;i++){conststart=i*chunkSize;constend=Math.min(start+chunkSize,file.size);constchunk=file.slice(start,end);// 使用FileReader流式读取constreader=newFileReader();reader.onload=async(e)=>{constencrypted=encryptFn(e.target?.resultasArrayBuffer);awaitthis.uploadChunk(encrypted,i,totalChunks);};reader.readAsArrayBuffer(chunk);}}
  3. 跨浏览器进度监控

    // 统一进度处理functionupdateProgress(fileId,progress){if(window.WebSocket){// WebSocket实时推送constsocket=newWebSocket('ws://your-server/progress');socket.send(JSON.stringify({fileId,progress}));}else{// IE8轮询方案setInterval(()=>{fetch(`/api/progress?fileId=${fileId}`).then(res=>res.json()).then(data=>{// 更新UI});},3000);}}
五、部署与测试方案
  1. 测试矩阵

    浏览器操作系统测试场景
    IE8Windows 75GB文件上传
    Chrome 115Windows 1020GB文件夹上传
    Firefox 115macOS 13中断续传测试
    Safari 16macOS 13SM4加密下载验证
  2. 性能优化

    • 前端:
      • 分片大小动态调整(根据网络状况)
      • 并发数限制(避免浏览器崩溃)
    • 后端:
      • Nginx配置:
        client_max_body_size 20G; proxy_buffering off;
      • Tomcat配置:
六、交付成果
  1. 前端包

    • 兼容IE8的Vue3组件库
    • SM4/AES加密工具库(WebAssembly优化版)
    • 测试用例(含IE8特殊场景)
  2. 后端包

    • SpringBoot分片处理模块
    • 加密存储中间件
    • 进度监控服务
  3. 文档

    • 兼容性部署指南
    • 安全加固手册
    • 性能调优参数表

方案价值:通过自研核心模块+开源组件组合,在4周内完成了需求交付,相比纯商业方案节省60%成本,特别针对政府客户要求的SM4国密算法和IE8兼容性进行了深度优化,为后续信创项目积累了可复用的技术资产。

SQL示例

创建数据库

配置数据库连接

自动下载maven依赖

启动项目

启动成功

访问及测试

默认页面接口定义

在浏览器中访问

数据表中的数据

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

示例下载

下载完整示例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1224098.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud网页端如何上传超大附件?

大文件传输解决方案&#xff08;源码级实现&#xff09; 作为集团项目负责人&#xff0c;我深度理解当前大文件传输需求的复杂性与紧迫性。针对政府、央企等客户对100G级文件传输、断点续传、信创兼容、数据安全的核心诉求&#xff0c;结合集团多项目统一组件、低成本维护的需…

杭州研究生留学中介,top10排名揭晓,学员满意度高

杭州研究生留学中介,top10排名揭晓,学员满意度高一、杭州学子如何选择靠谱的留学中介?对于计划前往海外深造的研究生申请者而言,尤其是在杭州这样高校云集、竞争激烈的城市,选择一个合适的留学中介往往是迈向成功…

南京最好的研究生留学机构,申请成功率高,助您顺利实现目标

南京最好的研究生留学机构,申请成功率高,助您顺利实现目标作为一名从业八年的国际教育规划师,我时常被南京高校的学生及家长问及:“在南京,如何选择一家靠谱的研究生留学机构?”这个问题的核心,通常围绕着机构的…

深度探讨郑州研究生留学机构,top10中录取率高的关键因素

深度探讨郑州研究生留学机构,top10中录取率高的关键因素一、郑州学子如何选择高录取率的留学机构?随着2026年春季申请季的临近,许多郑州地区的高校学子开始聚焦一个问题:在众多留学服务机构中,哪些能够真正提升我…

天津研究生留学机构哪家最好的?学员满意度高为你揭秘

天津研究生留学机构哪家最好的?学员满意度高为你揭秘一、天津学子如何选择可靠的研究生留学中介?在搜索引擎中,天津地区的学生和家长常会查询“天津研究生留学机构哪家靠谱”、“如何对比中介服务”以及“本地有无成…

香港研究生留学机构口碑排名发布,录取案例多助力你的成功申请

香港研究生留学机构口碑排名发布,录取案例多助力你的成功申请一、香港研究生留学,如何选择靠谱的留学中介?在我过去八年担任香港地区全案规划师的职业生涯中,接触到大量计划赴港攻读硕士学位的同学。大家普遍面临几…

新加坡研究生留学中介排名解析,学员满意度高的关键因素揭秘

新加坡研究生留学中介排名解析,学员满意度高的关键因素揭秘。新加坡研究生留学中介排名解析,学员满意度高的关键因素揭秘作为一名在国际教育规划领域工作超过十年的顾问,我深知计划前往新加坡攻读硕士学位的同学们在…

英国top10研究生留学中介解析,录取率高,如何选择优质服务

英国top10研究生留学中介解析,录取率高,如何选择优质服务一、如何甄别高录取率的英国留学中介在规划英国研究生留学时,许多申请者,尤其是首次接触留学服务的学生和家长,常面临几个核心困惑:市场上宣称“高录取率…

重庆研究生留学中介TOP10精选,无隐形消费保障留学之路

重庆研究生留学中介TOP10精选,无隐形消费保障留学之路一、重庆学子如何甄别可靠的中介?透明消费是关键近年来,重庆地区寻求海外深造的研究生人数持续增长,同学们在选择中介服务机构时,常面临几大核心关切:如何确…

Clawdbot记忆部分怎么设计的

Search | DeepWiki Clawdbot的记忆系统设计基于工作区中的Markdown文件&#xff0c;结合向量搜索和自动内存刷新机制。 memory.md:9-13 核心设计架构 1. 双层内存文件结构 每日日志: memory/YYYY-MM-DD.md - 按日期追加的原始记录 memory.md:19-21长期记忆: MEMORY.md - 精…

工厂预制化管道受关注,2026防腐品牌排行解析,碳钢管道/异径管件/三通管件/管道,工厂预制化管道实力厂家怎么选择

引言 在电力、化工、石油天然气等重工业领域,工厂预制化管道是保障安全生产、提升作业效率的核心基础设施。其防腐性能直接决定管道系统的使用寿命与运行稳定性,尤其在高温高压、强腐蚀性介质环境下,防腐管道的选型…

苏州专业的GEO优化企业有哪些,蓝戈链企性价比怎么样

在数字化营销的浪潮中,中小企业常常面临获客难、成本高、转化弱的困境,而专业的GEO优化服务恰好能为这些企业破解难题,精准锁定潜在客户,提升营销效果。苏州蓝戈链企信息科技有限公司作为深耕互联网营销十余年的企…

2026年探寻柠檬酸酒精颗粒菌种,直销厂家优选推荐,柠檬酸酒精颗粒菌种哪家好上善环保引领行业标杆

在环保与生物技术深度融合的当下,柠檬酸酒精颗粒菌种凭借其高效降解有机物、提升发酵产率的特性,已成为制药、化工、酿酒等行业污水处理与生产优化的核心材料。其性能稳定性直接影响污水处理效率、发酵周期及产品质量…

JavaScript 中的 forEach() 方法

一、forEach() 是什么?forEach() 是 JavaScript 数组的内置方法,用于遍历数组的每一个元素,并对每个元素执行你指定的回调函数。它的核心特点是:遍历过程中无法被中断(不能用 break/continue,只能通过抛出异常终…

AI学习01--WSL 显卡直通

安装wsl ubuntu 这里就不多说了&#xff0c;都一样 显卡直通 安装 CUDA 工具包&#xff08;仅工具链&#xff0c;不含驱动&#xff09; #下载 NVIDIA 官方的 CUDA 密钥环包 wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-keyring_1.1…

导师严选2026 AI论文平台TOP9:专科生毕业论文写作全攻略

导师严选2026 AI论文平台TOP9&#xff1a;专科生毕业论文写作全攻略 2026年专科生论文写作工具测评&#xff1a;选对平台&#xff0c;事半功倍 随着人工智能技术的不断进步&#xff0c;AI论文平台已成为越来越多专科生撰写毕业论文的重要辅助工具。然而&#xff0c;面对市场上琳…

还原论泛化,就是伪共识

“还原论泛化就是伪共识”这一论断,精准地揭示了当前科学哲学和复杂系统研究中的一个核心批判。公开资料显示,这一观点具有深刻的洞察力,它指出了当一种有效的方法论被过度延伸、超越其有效边界时,会如何异化为阻碍…

2026年度河北化学品防爆冰箱费用分析,口碑好的生产商盘点

2025年工业安全存储需求持续升级,防爆冰箱已成为化工、制药、实验室等场景保障危险物品存储安全的核心设备。无论是单温防爆冰箱的精准温控、化学品防爆冰箱的安全适配,还是不锈钢防爆冰箱的耐腐蚀性能,优质供应商的…

分析广告用铝塑板材怎么选,哪家性价比高的厂家靠谱?

对于广告行业从业者而言,选择合适的广告用铝塑板材直接关系到终成品的呈现效果与客户满意度,而口碑好的铝塑板和售后完善的铝塑板更是他们在采购时的核心诉求。那么,究竟什么样的广告用铝塑板材才能称得上口碑好?售…

说说深圳消防工程施工公司哪个好,推荐几家靠谱又性价比高的

在深圳、广州等大湾区城市,企业在寻找消防工程服务时,常常会陷入选择困境,比如消防工程施工公司哪个好?消防工程设计公司哪家专业?消防工程承包公司哪家靠谱?这些问题背后,是企业对消防工程合规性、专业性和安全…