Java需依赖Web框架或底层API实现HTTP文件上传下载;Spring Boot最常用,须校验空文件、防路径穿越、设大小限制;下载需正确设置响应头及流式传输;HttpURLConnection上传需手动构造multipart body。

Java 本身不内置 HTTP 文件上传下载服务,必须依赖 Web 框架(如 Spring Boot)或底层网络 API(如 HttpURLConnection、Socket)来实现。纯 Java SE 无法直接处理浏览器表单提交的 multipart/form-data,也缺乏开箱即用的文件流代理能力。
Spring Boot + RestController 实现上传(支持多文件)
这是最常用、生产就绪的方式。关键点不是“怎么写一个方法”,而是如何正确解析 MultipartFile 并规避临时文件残留、内存溢出、路径遍历等风险。
-
@RequestParam("file") MultipartFile file只能接收单个文件;多文件需用@RequestParam("files") Listfiles - 务必校验
file.isEmpty(),否则空提交会触发NullPointerException或静默失败 - 不要直接拼接
file.getOriginalFilename()构造本地路径——它可能含../,导致路径穿越;应使用FilenameUtils.getName()(Apache Commons IO)或白名单后缀过滤 - 建议设置上传限制:
spring.servlet.multipart.max-file-size=10MB和max-request-size=10MB,否则大文件可能卡住 Tomcat 线程
用 ResponseEntity 下载文件(避免中文名乱码)
下载的核心不是返回文件内容,而是正确设置响应头。常见错误是只设 Content-Type,却忽略 Content-Disposition 中的编码逻辑。
- 对英文文件名:直接用
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); - 对中文文件名:必须用
URLEncoder.encode(fileName, "UTF-8"),并加filename*=UTF-8''格式(RFC 5987),例如:attachment; filename="abc.pdf"; filename*=UTF-8''%E4%BD%A0%E5%A5%BD.pdf - 不要用
new FileSystemResource(filePath)直接返回大文件——会全量加载进内存;应改用UrlResource(Paths.get(filePath)),配合response.getOutputStream()流式传输 - 务必检查文件是否存在且可读,否则抛
ResponseStatusException(HttpStatus.NOT_FOUND)而非让框架返回 500
不用 Web 框架时,如何用 HttpURLConnection 发起上传请求
适用于客户端调用(比如后台服务向另一个系统上传),不推荐用于浏览器端交互。难点在于手动构造符合 RFC 7578 的 multipart body。
一套面向小企业用户的企业网站程序!功能简单,操作简单。实现了小企业网站的很多实用的功能,如文章新闻模块、图片展示、产品列表以及小型的下载功能,还同时增加了邮件订阅等相应模块。公告,友情链接等这些通用功能本程序也同样都集成了!同时本程序引入了模块功能,只要在系统默认模板上创建模块,可以在任何一个语言环境(或任意风格)的适当位置进行使用!
立即学习“Java免费学习笔记(深入)”;
- 必须设置
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary),且boundary需随机生成(如"----" + System.currentTimeMillis()) - 每个 part 之间要用
--boundary分隔,结尾用--boundary--;文本字段和文件字段的格式不同,文件字段还需额外写入Content-Disposition: form-data; name="file"; filename="a.txt"和Content-Type: text/plain - 不能用
PrintWriter写二进制文件内容——会破坏字节;必须用OutputStream原始写入 - 上传完成后需调用
connection.getResponseCode()才真正发送请求,否则只是“准备好了”
真正难的从来不是“怎么把字节发过去”,而是边界情况:上传中断时的清理、并发写同一目录的锁竞争、磁盘满时的降级策略、病毒扫描集成、断点续传支持……这些在简单示例里根本不会出现,但上线第一天就会撞上。









