news 2026/3/22 1:41:35

Java如何结合AES加密实现大附件上传的加密传输与存储?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java如何结合AES加密实现大附件上传的加密传输与存储?

大文件传输解决方案建议书

一、需求分析与技术挑战

作为福建IT行业软件公司项目负责人,针对贵司提出的大文件传输需求,我进行了全面分析,发现以下几个核心挑战:

  1. 超大文件传输稳定性:单文件100G的传输及断点续传
  2. 文件夹结构保持与传输:现有开源组件大多不支持或不够成熟
  3. 非打包下载方案:避免服务器内存崩溃
  4. 跨平台兼容性:需支持老旧系统如Windows 7+IE8
  5. 加密传输与存储:支持国密SM4和AES
  6. 项目集成复杂度:需兼容现有JSP、SpringBoot、Vue2/3、React等技术栈

二、解决方案架构设计

1. 整体架构

[客户端] ←HTTPS→ [Nginx负载均衡] ←→ [应用服务器集群] ←→ [MySQL/SQL Server/Oracle] ↑ ↓ [阿里云OSS/私有存储]

2. 关键技术方案

文件分块传输机制
  • 采用动态分块策略(1-10MB/块),根据网络状况自动调整
  • 分块信息记录到数据库,支持跨会话断点续传
文件夹结构保持
  • 设计专门的元数据结构,记录文件夹层级关系
  • 传输前先同步目录结构,再传输文件内容
非打包下载方案
  • 采用流式传输技术,避免内存中打包
  • 服务器端仅做文件索引和流控
加密方案
  • 传输加密:TLS+应用层加密双重保障
  • 存储加密:支持SM4/AES可配置

三、代码实现方案

后端核心代码(JSP/SpringBoot)

文件分块上传接口
// FileUploadController.java (SpringBoot示例)@PostMapping("/uploadChunk")publicResponseEntityuploadChunk(@RequestParam("file")MultipartFilefile,@RequestParam("chunkNumber")intchunkNumber,@RequestParam("totalChunks")inttotalChunks,@RequestParam("identifier")Stringidentifier,@RequestParam("filename")Stringfilename,@RequestParam("relativePath")StringrelativePath){// 校验分块if(file.isEmpty()){returnResponseEntity.badRequest().body("Empty chunk");}// 存储分块到临时目录StringtempDir=getTempDir(identifier);StringchunkFilename=chunkNumber+".part";FilechunkFile=newFile(tempDir,chunkFilename);try{file.transferTo(chunkFile);// 记录分块信息到数据库uploadService.recordChunk(identifier,filename,relativePath,chunkNumber,totalChunks);// 检查是否所有分块已上传if(uploadService.checkAllChunksUploaded(identifier,totalChunks)){returnassembleFile(identifier,filename,relativePath);}returnResponseEntity.ok().body("Chunk uploaded");}catch(IOExceptione){returnResponseEntity.status(500).body("Upload failed");}}
文件合并逻辑
privateResponseEntityassembleFile(Stringidentifier,Stringfilename,StringrelativePath){StringtempDir=getTempDir(identifier);FiletempDirFile=newFile(tempDir);// 获取所有分块文件File[]chunks=tempDirFile.listFiles((dir,name)->name.matches("\\d+\\.part"));if(chunks==null||chunks.length==0){returnResponseEntity.status(500).body("No chunks found");}// 按分块编号排序Arrays.sort(chunks,Comparator.comparingInt(f->Integer.parseInt(f.getName().split("\\.")[0])));// 创建目标文件StringsavePath=getSavePath(relativePath);FiledestFile=newFile(savePath,filename);try(FileOutputStreamfos=newFileOutputStream(destFile,true)){// 合并所有分块for(Filechunk:chunks){Files.copy(chunk.toPath(),fos);chunk.delete();// 删除已合并的分块}// 记录完整文件信息uploadService.recordCompleteFile(identifier,filename,relativePath,destFile.length());returnResponseEntity.ok().body("File assembled");}catch(IOExceptione){returnResponseEntity.status(500).body("Assembly failed");}}

前端核心代码(Vue2示例)

文件上传组件
// LargeFileUploader.vueexportdefault{data(){return{fileList:[],chunkSize:5*1024*1024,// 5MBconcurrentLimit:3,activeUploads:0}},methods:{handleFileChange(e){constfiles=Array.from(e.target.files);this.fileList=files.map(file=>({id:this.generateFileId(file),fileObject:file,name:file.name,relativePath:file.webkitRelativePath||'',size:file.size,progress:0,chunks:Math.ceil(file.size/this.chunkSize),uploadedChunks:0}));},generateFileId(file){return`${file.name}-${file.size}-${file.lastModified}-${Math.random().toString(36).substr(2,9)}`;}}}

四、IE8兼容方案

1. 前端兼容处理

// ie8-wrapper.js(function(){// 添加File API polyfillif(typeofwindow.File==='undefined'){window.File=function(){};}// 添加FormData polyfillif(typeofFormData==='undefined'){window.FormData=function(){this.data=[];this.append=function(key,value){this.data.push({key:key,value:value});};this._getData=function(){returnthis.data;};};}// XMLHttpRequest增强varoriginalXHROpen=XMLHttpRequest.prototype.open;XMLHttpRequest.prototype.open=function(method,url,async,user,password){// 保存请求信息供send方法使用this._method=method;this._url=url;originalXHROpen.apply(this,arguments);};varoriginalXHRSend=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.send=function(data){if(datainstanceofFormData){// 处理FormData polyfillvarfd=data._getData();varboundary='----WebKitFormBoundary'+Math.random().toString(36).substr(2);varbody='';for(vari=0;i<fd.length;i++){body+='--'+boundary+'\r\n';body+='Content-Disposition: form-data; name="'+fd[i].key+'"';if(fd[i].valueinstanceofFile){body+='; filename="'+fd[i].value.name+'"\r\n';body+='Content-Type: '+fd[i].value.type+'\r\n\r\n';// 实际处理中需要读取文件内容body+='[FILE_CONTENT]\r\n';}else{body+='\r\n\r\n'+fd[i].value+'\r\n';}}body+='--'+boundary+'--\r\n';this.setRequestHeader('Content-Type','multipart/form-data; boundary='+boundary);data=body;}originalXHRSend.call(this,data);};})();

2. 后端兼容处理

// IE8MultipartFilter.javapublicclassIE8MultipartFilterimplementsFilter{@OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{HttpServletRequesthttpRequest=(HttpServletRequest)request;StringcontentType=httpRequest.getContentType();// 检查是否是IE8的特殊multipart请求if(contentType!=null&&contentType.contains("multipart/form-data")){StringuserAgent=httpRequest.getHeader("User-Agent");if(userAgent!=null&&userAgent.contains("MSIE 8")){// 对IE8的特殊处理HttpServletRequestwrappedRequest=newIE8CompatibleMultipartHttpServletRequest(httpRequest);chain.doFilter(wrappedRequest,response);return;}}chain.doFilter(request,response);}}

五、数据库设计

1. 文件上传记录表

CREATETABLE`file_uploads`(`id`bigint(20)NOTNULLAUTO_INCREMENT,`identifier`varchar(64)NOTNULLCOMMENT'文件唯一标识',`filename`varchar(255)NOTNULLCOMMENT'原始文件名',`filepath`varchar(512)NOTNULLCOMMENT'存储路径',`relative_path`varchar(512)DEFAULT''COMMENT'相对路径(用于文件夹结构)',`filesize`bigint(20)NOTNULLCOMMENT'文件大小(字节)',`status`tinyint(4)NOTNULLDEFAULT'0'COMMENT'状态:0-上传中,1-已完成,2-已取消',`created_at`datetimeNOTNULLDEFAULTCURRENT_TIMESTAMP,`completed_at`datetimeDEFAULTNULL,`user_id`bigint(20)DEFAULTNULLCOMMENT'上传用户ID',`encryption_type`varchar(20)DEFAULTNULLCOMMENT'加密类型:SM4/AES',`encryption_key`varchar(512)DEFAULTNULLCOMMENT'加密密钥(加密存储)',PRIMARYKEY(`id`),UNIQUEKEY`idx_identifier`(`identifier`),KEY`idx_user_status`(`user_id`,`status`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COMMENT='文件上传主记录';

2. 文件分块记录表

CREATETABLE`file_chunks`(`id`bigint(20)NOTNULLAUTO_INCREMENT,`upload_id`bigint(20)NOTNULLCOMMENT'关联file_uploads.id',`identifier`varchar(64)NOTNULLCOMMENT'文件唯一标识',`chunk_number`int(11)NOTNULLCOMMENT'分块编号',`chunk_size`int(11)NOTNULLCOMMENT'分块大小(字节)',`chunk_path`varchar(512)DEFAULTNULLCOMMENT'分块存储路径',`upload_time`datetimeNOTNULLDEFAULTCURRENT_TIMESTAMP,`checksum`varchar(64)DEFAULTNULLCOMMENT'分块校验和',PRIMARYKEY(`id`),UNIQUEKEY`idx_identifier_chunk`(`identifier`,`chunk_number`),KEY`idx_upload_id`(`upload_id`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COMMENT='文件分块记录';

3. 文件夹结构记录表

CREATETABLE`folder_structures`(`id`bigint(20)NOTNULLAUTO_INCREMENT,`upload_id`bigint(20)NOTNULLCOMMENT'关联file_uploads.id',`parent_id`bigint(20)DEFAULTNULLCOMMENT'父文件夹ID',`name`varchar(255)NOTNULLCOMMENT'文件夹名',`relative_path`varchar(512)NOTNULLCOMMENT'相对路径',`created_at`datetimeNOTNULLDEFAULTCURRENT_TIMESTAMP,PRIMARYKEY(`id`),KEY`idx_upload_id`(`upload_id`),KEY`idx_parent_id`(`parent_id`),KEY`idx_relative_path`(`relative_path`(255)))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COMMENT='文件夹结构记录';

六、部署方案

1. 服务器配置建议

  • 应用服务器:4核8G内存起步,根据并发量扩展
  • 数据库服务器:8核16G内存+SSD存储,建议主从配置
  • 存储服务器:与阿里云OSS对接或自建分布式存储

2. 负载均衡配置

client → [Nginx负载均衡] → [应用服务器1] ↘→ [应用服务器2] ↘→ [应用服务器3]

3. 高可用方案

  • 数据库主从复制+读写分离
  • Redis集群用于会话和临时数据存储
  • 分布式文件锁机制避免并发问题

七、商务合作方案

基于贵司需求,我们提供以下两种合作模式:

  1. 买断授权方案(推荐)

    • 一次性费用:98万元
    • 包含:不限项目数的永久使用权、源代码交付、5年免费维护
    • 额外服务:3次现场技术培训、5个工作日现场部署支持
  2. 按项目授权方案

    • 单项目授权费:1.8万元/项目
    • 年费模式:首年18万元(10个项目),次年按实际项目数结算
    • 包含:标准版授权、1年免费维护

导入项目

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

工程

NOSQL

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

创建数据表

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

修改数据库连接信息

访问页面进行测试

文件存储路径

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

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

批量下载

支持文件批量下载

下载续传

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

文件夹下载

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

下载示例

点击下载完整示例

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

从混乱到清晰:AI架构师的实验数据清洗技巧

从混乱到清晰:AI架构师的实验数据清洗技巧 图1:数据清洗在AI项目中的核心地位与流程概览 章节一:数据清洗的基础理论与重要性 1.1 核心概念 数据清洗(Data Cleaning),也称为数据清理或数据净化,是指识别、纠正或移除数据集中存在的不准确、不完整、不一致、重复或无关…

作者头像 李华
网站建设 2026/3/21 4:49:40

17、Windows Azure Blob 存储服务全解析

Windows Azure Blob 存储服务全解析 1. 定价模式 Windows Azure 存储服务的定价规则较为清晰。每月每存储 1GB 数据收费 0.15 美元,每 10000 次存储事务收费 0.01 美元,数据传入带宽每 GB 收费 0.10 美元,数据传出带宽每 GB 收费 0.15 美元。 这种定价模式适用于 Windows…

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

【独家披露】某头部AI公司内部使用的Open-AutoGLM部署手册流出

第一章&#xff1a;Open-AutoGLM部署概述Open-AutoGLM 是一个开源的自动化大语言模型推理服务框架&#xff0c;专为高效部署和管理 GLM 系列模型而设计。它支持多种后端运行时&#xff08;如 vLLM、HuggingFace Transformers&#xff09;和灵活的 API 接口封装&#xff0c;适用…

作者头像 李华
网站建设 2026/3/18 18:31:19

28、探索全文搜索与数据建模

探索全文搜索与数据建模 1. 添加迷你控制台 为了能够测试不同的文本文件并搜索各种术语,我们需要添加一个迷你控制台。将 Program.cs 替换为以下代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using…

作者头像 李华
网站建设 2026/3/21 18:35:48

为什么开发者都在用anything-llm镜像做RAG应用?

为什么开发者都在用 anything-llm 镜像做 RAG 应用&#xff1f; 在大模型热潮席卷各行各业的今天&#xff0c;越来越多团队开始尝试将 LLM 引入实际业务——从智能客服到内部知识问答&#xff0c;从个人助手到企业大脑。但很快就会遇到一个现实问题&#xff1a;通义千问、GPT …

作者头像 李华
网站建设 2026/3/13 8:04:48

anything-llm全面解析:为什么它是最佳个人AI助手?

Anything-LLM 全面解析&#xff1a;为什么它是最佳个人 AI 助手&#xff1f; 在生成式 AI 迅速渗透办公与知识管理的今天&#xff0c;一个核心问题日益凸显&#xff1a;我们如何让大模型真正“懂”自己的文档&#xff1f;通用聊天机器人虽然能对答如流&#xff0c;但面对一份内…

作者头像 李华