# file-shard-upload **Repository Path**: liudechang/file-shard-upload ## Basic Information - **Project Name**: file-shard-upload - **Description**: 文件分片上传 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-07 - **Last Updated**: 2026-03-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # File Shard Upload 一个企业级可扩展的文件分片上传中间件,支持大文件分片上传、断点续传、并发控制等功能。 ## 项目简介 File Shard Upload 是一个基于 Spring Boot 2.7.18 开发的企业级文件分片上传中间件,采用模块化架构设计,支持高并发上传、文件校验、多种存储后端等企业级特性。 ## 核心特性 - **分片上传**:支持将大文件切分为多个固定大小的分片,按序或并发上传 - **断点续传**:服务端记录已上传分片信息,支持客户端从断点继续上传 - **并发控制**:限制单个文件或单个用户的同时上传分片数量 - **用户任务限制**:限制单用户同时执行的导入任务数 - **文件校验**:支持文件类型白名单校验和 MD5/SHA256 校验防篡改 - **多种存储后端**:支持本地磁盘和对象存储(MinIO/S3) - **详细日志**:记录上传生命周期中的关键事件,支持查询和审计 ## 技术栈 - **框架**:Spring Boot 2.7.18 - **数据存储**:JPA / MyBatisPlus - **缓存**:Redis - **数据库**:MySQL / PostgreSQL - **构建工具**:Maven 3.x ## 项目结构 ``` file-shard-upload/ ├── pom.xml # 父POM ├── file-shard-upload-common/ # 公共模块 │ ├── src/main/java/ │ │ └── com/fileshard/common/ │ │ ├── entity/ # 实体类 │ │ ├── enums/ # 枚举类 │ │ ├── repository/ # 数据访问接口 │ │ ├── service/ # 服务接口 │ │ ├── strategy/ # 存储策略接口 │ │ ├── utils/ # 工具类 │ │ └── vo/ # 视图对象 │ └── src/main/resources/ # 公共资源 ├── file-shard-upload-repository/ # 数据访问模块 │ ├── src/main/java/ │ │ └── com/fileshard/repository/ │ │ ├── impl/ # 数据访问实现 │ │ └── config/ # 配置类 │ └── src/main/resources/ # 资源文件 ├── file-shard-upload-service/ # 业务逻辑模块 │ ├── src/main/java/ │ │ └── com/fileshard/service/ │ │ ├── impl/ # 服务实现 │ │ └── aspect/ # AOP切面 │ └── src/main/resources/ # 资源文件 └── file-shard-upload-controller/ # API控制器模块 ├── src/main/java/ │ └── com/fileshard/controller/ └── src/main/resources/ # 资源文件 ``` ## 快速开始 ### 环境要求 - JDK 1.8+ - Maven 3.6+ - MySQL 5.7+ / PostgreSQL 12+ - Redis 6.x+ ### 编译项目 ```bash mvn clean compile -DskipTests ``` ### 运行项目 ```bash mvn spring-boot:run -pl file-shard-upload-controller ``` ### 打包 ```bash mvn clean package -DskipTests ``` ## 配置说明 ### application.yml ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/file_upload?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: your_password driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update naming: physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl show-sql: true redis: host: localhost port: 6379 password: file: upload: # 分片大小(字节),默认5MB chunk-size: 5242880 # 本地存储路径 storage-path: ./uploads # 最大并发分片数 max-concurrent-chunks: 3 # 单用户最大并发任务数 max-user-tasks: 2 # 文件类型白名单 allowed-types: jpg,jpeg,png,gif,pdf,doc,docx,xls,xlsx ``` ## API 文档 ### 1. 初始化上传任务 **POST** `/upload/init` 请求体: ```json { "fileName": "example.pdf", "fileSize": 104857600, "fileMd5": "d41d8cd98f00b204e9800998ecf8427e", "chunkSize": 5242880, "storageType": 0 } ``` 响应: ```json { "code": 200, "message": "success", "data": { "uploadId": "550e8400-e29b-41d4-a716-446655440000" } } ``` ### 2. 上传分片 **POST** `/upload/chunk` 请求参数: - file: 分片文件 - uploadId: 上传任务ID - chunkIndex: 分片索引(从0开始) - totalChunks: 总分片数 - chunkSize: 分片大小(字节) - chunkMd5: 分片MD5(可选) 响应: ```json { "code": 200, "message": "success", "data": true } ``` ### 3. 合并分片 **POST** `/upload/complete` 请求体: ```json { "uploadId": "550e8400-e29b-41d4-a716-446655440000", "fileName": "example.pdf", "totalChunks": 20 } ``` 响应: ```json { "code": 200, "message": "success", "data": { "filePath": "/uploads/550e8400-e29b-41d4-a716-446655440000/example.pdf", "fileSize": 104857600, "fileMd5": "d41d8cd98f00b204e9800998ecf8427e" } } ``` ### 4. 查询上传进度 **GET** `/upload/progress` 请求参数: - uploadId: 上传任务ID 响应: ```json { "code": 200, "message": "success", "data": { "uploadId": "550e8400-e29b-41d4-a716-446655440000", "fileName": "example.pdf", "totalChunks": 20, "uploadedChunks": [0, 1, 2, 4, 5], "progress": 25.0, "status": "UPLOADING" } } ``` ### 5. 取消上传任务 **DELETE** `/upload` 请求参数: - uploadId: 上传任务ID 响应: ```json { "code": 200, "message": "success", "data": true } ``` ## 数据库设计 ### t_upload_task(上傳任務表) | 字段名 | 类型 | 说明 | |--------|------|------| | id | BIGINT | 主键 | | upload_id | VARCHAR(64) | 上传任务唯一标识 | | user_id | VARCHAR(64) | 用户ID | | file_name | VARCHAR(255) | 文件名 | | file_size | BIGINT | 文件大小 | | file_md5 | VARCHAR(64) | 文件MD5 | | total_chunks | INT | 总分片数 | | uploaded_chunks | INT | 已上传分片数 | | chunk_size | BIGINT | 分片大小 | | storage_type | INT | 存储类型(0:本地, 1:MinIO, 2:S3) | | status | VARCHAR(20) | 任务状态 | | file_path | VARCHAR(512) | 文件存储路径 | | created_time | DATETIME | 创建时间 | | updated_time | DATETIME | 更新时间 | ### t_upload_chunk(分片信息表) | 字段名 | 类型 | 说明 | |--------|------|------| | id | BIGINT | 主键 | | upload_id | VARCHAR(64) | 上传任务ID | | chunk_index | INT | 分片索引 | | chunk_size | BIGINT | 分片大小 | | chunk_md5 | VARCHAR(64) | 分片MD5 | | chunk_path | VARCHAR(512) | 分片存储路径 | | status | VARCHAR(20) | 分片状态 | | created_time | DATETIME | 创建时间 | | updated_time | DATETIME | 更新时间 | ### t_user_task_limit(用户任务限制表) | 字段名 | 类型 | 说明 | |--------|------|------| | id | BIGINT | 主键 | | user_id | VARCHAR(64) | 用户ID | | current_tasks | INT | 当前任务数 | | max_tasks | INT | 最大任务数 | | created_time | DATETIME | 创建时间 | | updated_time | DATETIME | 更新时间 | ## 架构设计 ``` ┌─────────────────────────────────────────────────────────────┐ │ UploadController │ │ (API入口:/upload/init, /chunk, /complete) │ └─────────────────────────┬───────────────────────────────────┘ │ ┌─────────────────────────▼───────────────────────────────────┐ │ UploadService │ │ (业务逻辑处理层) │ └─────────┬───────────────┬───────────────┬───────────────────┘ │ │ │ ┌─────────▼─────────┐ ┌───▼─────┐ ┌──────▼────────┐ │ ConcurrentControl │ │ Storage │ │ Logger │ │ Service │ │Strategy │ │ Service │ └───────────────────┘ └─────────┘ └───────────────┘ │ ┌─────────▼─────────┐ │ Redis │ │ (并发控制/限流) │ └───────────────────┘ │ ┌─────────▼─────────┐ │ Repository │ │ (JPA/MyBatisPlus) │ └─────────┬─────────┘ │ ┌─────────▼─────────┐ │ MySQL │ │ (任务/分片元数据) │ └───────────────────┘ ``` ## 扩展说明 ### 集成到现有项目 1. 添加依赖: ```xml com.fileshard file-shard-upload-controller 1.0.0 ``` 2. 配置数据库和Redis 3. 启动类扫描包路径添加: ```java @ComponentScan(basePackages = {"com.fileshard"}) ``` ### 自定义存储策略 实现 `StorageStrategy` 接口并注册为 Spring Bean: ```java @Configuration public class StorageConfig { @Bean public StorageStrategy customStorageStrategy() { return new CustomStorageStrategy(); } } ``` ## 错误码说明 | 错误码 | 说明 | |--------|------| | 200 | 成功 | | 400 | 参数错误 | | 401 | 未授权 | | 403 | 禁止访问 | | 404 | 资源不存在 | | 500 | 服务器内部错误 | | 1001 | 上传任务不存在 | | 1002 | 分片上传失败 | | 1003 | 分片合并失败 | | 1004 | 并发数超限 | | 1005 | 用户任务数超限 | | 1006 | 文件类型不允许 | | 1007 | 文件MD5校验失败 | ## License 本项目采用 Apache License 2.0 开源协议。