
本文详解如何将 spring boot 中基于 @requestparam 的字符串参数接收方式,升级为安全、健壮地接收客户端上传的 .txt 文件,并完成内容读取与业务处理。
本文详解如何将 spring boot 中基于 @requestparam 的字符串参数接收方式,升级为安全、健壮地接收客户端上传的 .txt 文件,并完成内容读取与业务处理。
在实际开发中,直接通过 URL 传递长文本(如 ?text=this+is+a+string)存在明显局限:URL 长度受限(通常不超过 2048 字符)、不支持特殊字符编码、无法传输二进制或换行内容,且不符合 RESTful 设计规范。当需求明确指向“接收一个 .txt 文件”时,应采用标准的 文件上传(Multipart)机制,而非依赖本地文件路径(如答案中 new File(filePath) 的方式)——后者存在严重安全隐患(路径遍历、服务端任意文件读取)、强耦合部署环境,且完全违背 REST 接口的无状态与可移植原则。
✅ 正确做法是使用 MultipartFile 接收客户端以 multipart/form-data 方式上传的文本文件:
@PostMapping(value = "/test-file", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseBody
public String processTextFile(@RequestParam("file") MultipartFile file) throws IOException {
// 校验非空与类型
if (file.isEmpty()) {
throw new IllegalArgumentException("文件不能为空");
}
if (!"text/plain".equalsIgnoreCase(file.getContentType()) &&
!file.getOriginalFilename().toLowerCase().endsWith(".txt")) {
throw new IllegalArgumentException("仅支持 .txt 文本文件");
}
// 安全读取内容(自动处理编码,推荐 UTF-8)
String content = new String(file.getBytes(), StandardCharsets.UTF_8);
// 或逐行读取(适用于大文件流式处理)
// try (BufferedReader reader = new BufferedReader(
// new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8))) {
// return modified(reader.lines().collect(Collectors.joining("\n")));
// }
return modified(content.trim());
}? 关键说明与最佳实践:
- HTTP 方法必须为 POST(或 PUT):GET 不支持请求体上传,@RequestParam("file") 在 @GetMapping 下无效;
- consumes = MediaType.MULTIPART_FORM_DATA_VALUE 显式声明媒体类型,提升接口契约清晰度;
- 严格校验 file.getContentType() 和文件扩展名,防止恶意伪装(如上传 .jsp 冒充 .txt);
- 优先使用 file.getBytes() + StandardCharsets.UTF_8 读取,避免 FileReader(默认平台编码,易乱码);
- 大文件场景请用 InputStream 流式处理,避免内存溢出;
- 禁止接受客户端传入的任意文件路径(如 filePath 参数)——这是高危反模式,会导致服务器敏感文件泄露(如 /etc/passwd)。
调用示例(cURL):
curl -X POST "http://localhost:8080/test-file" \ -F "file=@example.txt;type=text/plain"
其中 example.txt 内容为 this is a string,接口将返回 This is a string!。
综上,REST 接口处理文本文件的本质,是遵循 HTTP 协议规范,以安全、可移植、可测试的方式接收 multipart 数据,而非绕过协议直接操作服务端文件系统。

















