Java:文件上传
文件上传是 Web 应用的核心功能,允许客户端将图片、文档、压缩包等文件发送到服务器保存。:若未做安全校验,极易被上传,导致服务器被入侵。
·
一、文件上传 基础概念
文件上传是 Web 应用的核心功能,允许客户端将图片、文档、压缩包等文件发送到服务器保存。核心风险:若未做安全校验,极易被上传木马、后门、恶意脚本,导致服务器被入侵。
二、基本原理
1. 客户端流程
- 使用
<form>表单提交 - 必须设置:
enctype="multipart/form-data" - 使用
<input type="file">选择文件 - 浏览器将文件拆分为 ** multipart 数据流 ** 发送
2. 服务端流程
- 接收 multipart 数据流
- 解析:文件名、MIME 类型、文件内容、表单字段
- 校验文件合法性(类型、大小、后缀、内容)
- 生成安全文件名,写入磁盘 / 云存储
- 返回访问路径或结果
三、核心技术与依赖
1. Servlet 3.0+ 原生上传
- 无需第三方包
- 注解:
@MultipartConfig - 方法:
request.getPart()/getParts()
2. Apache Commons FileUpload
- 兼容低版本 Servlet
- 依赖:
commons-fileupload+commons-io
3. Spring 系列(Spring Boot / Spring MVC)
- 接口:
MultipartFile - 自动封装解析逻辑
- 企业开发首选
四、具体实现(代码完善版)
1. Servlet 3.0+ 原生实现
前端表单
<form action="/upload" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"><br>
上传文件:<input type="file" name="file"><br>
<button type="submit">提交</button>
</form>
服务端 Servlet
@WebServlet("/upload")
@MultipartConfig(
fileSizeThreshold = 1024 * 1024, // 1MB 内存阈值
maxFileSize = 1024 * 1024 * 10, // 单文件最大 10MB
maxRequestSize = 1024 * 1024 * 50 // 总请求最大 50MB
)
public class FileUploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
String username = request.getParameter("username");
Part part = request.getPart("file");
String fileName = part.getSubmittedFileName();
// 安全处理:UUID 重命名,防止覆盖与路径穿越
String suffix = fileName.substring(fileName.lastIndexOf("."));
String uuidName = UUID.randomUUID() + suffix;
String savePath = getServletContext().getRealPath("/uploads");
File dir = new File(savePath);
if (!dir.exists()) dir.mkdirs();
part.write(savePath + File.separator + uuidName);
response.getWriter().write("上传成功:" + uuidName);
}
}
2. Spring Boot 实现(企业标准写法)
Controller(最安全、最规范)
@RestController
@RequestMapping("/api")
public class UploadController {
// 上传目录(建议写到 application.yml)
private static final String UPLOAD_PATH = "D:/uploads/";
@PostMapping("/upload")
public Result upload(
@RequestParam String username,
@RequestParam MultipartFile file) {
if (file.isEmpty()) {
return Result.fail("请选择文件");
}
// 1. 校验文件类型(白名单)
String contentType = file.getContentType();
List<String> allowTypes = Arrays.asList(
"image/jpeg", "image/png", "image/gif"
);
if (!allowTypes.contains(contentType)) {
return Result.fail("不允许的文件类型");
}
// 2. 安全文件名(UUID)
String original = file.getOriginalFilename();
String suffix = original.substring(original.lastIndexOf("."));
String newName = UUID.randomUUID() + suffix;
try {
Files.write(Paths.get(UPLOAD_PATH + newName), file.getBytes());
return Result.success("上传成功:" + newName);
} catch (IOException e) {
return Result.fail("上传失败:" + e.getMessage());
}
}
}
application.yml 配置(推荐)
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 50MB
五、关键配置与优化
- 文件大小限制
- maxFileSize:单文件上限
- maxRequestSize:整个请求上限
- 临时文件目录
- 防止系统自动清理导致上传失败
- 文件名安全处理
- 使用 UUID 重命名
- 过滤
/ \ .. : * ?等特殊字符
- 存储方案
- 单机:本地目录
- 分布式:阿里云 OSS / 腾讯云 COS / MinIO
六、安全风险与防御
1. 常见漏洞
- 文件上传漏洞:上传
.jsp.php.asp木马 - 路径穿越:文件名使用
../穿透目录 - 文件名覆盖:同名文件覆盖服务器文件
- 超大文件攻击:占用磁盘与带宽
2. 防御措施(必须全部做)
- 后缀白名单:只允许
.jpg/.png/.gif/.pdf - MIME 类型校验
- 文件内容校验:检查文件头(幻数)
- 重命名文件:UUID 生成新名称
- 上传目录不可执行:禁止解析脚本
- 限制文件大小
- 病毒扫描(企业级)
- 存储到非 Web 目录
七、高级功能
- 分片上传:大文件分块上传、断点续传
- 异步上传:Ajax / Axios 无刷新上传
- 跨域支持:
@CrossOrigin/ 网关配置 - 预览 / 下载:提供静态资源映射
- 水印 / 压缩:图片处理
八、思维导图

九、考试 / 面试必背高频要点
- 文件上传表单必须加:
enctype="multipart/form-data" - Spring 上传使用接口:
MultipartFile - 最容易出现的漏洞:文件上传漏洞
- 防御三件套:后缀白名单 + 类型校验 + UUID 重命名
- 上传目录必须:不可执行脚本
- 大文件方案:分片上传
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)