场景
使用openfeign转发MultipartFile类型的文件时出现了下面的错误。
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ApiOperation(value = "导入")
public ResponseJson<String> uploadFiles(@RequestParam("files") MultipartFile[] files) {
for (MultipartFile file : files) {
if (!isExcelFile(file)) {
return ResponseJson.fail("文件格式错误. 只支持.xls和.xlsx文件格式");
}
}
}
org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
分析原因后发现,请求中并没有正确设置请求头部中 Content-Type
为 multipart/form-data
的类型。
multipart/form-data
是一种 HTTP 请求的内容类型(Content-Type),它被设计用来支持文件上传以及提交表单数据。
解决
对于文件格式,Spring提供了用于处理文件上传的注解@RequestParam
,只需要将@RequestPart
即可解决问题。
openFeign接口代码:
@FeignClient(name = "anti-fraud-web-ruleDesign",path = "/calculationTemplate")
public interface CalculationTemplateClient {
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
ResponseJson<String> uploadFiles(@RequestPart("files") MultipartFile[] files);
}
被调用服务接口:
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ApiOperation(value = "导入")
public ResponseJson<String> uploadFiles(@RequestPart("files") MultipartFile[] files) {
for (MultipartFile file : files) {
if (!isExcelFile(file)) {
return ResponseJson.fail("文件格式错误. 只支持.xls和.xlsx文件格式");
}
}
}
@RequestParam
和@RequestPart
的区别
在 Spring Framework 中,@RequestParam
和 @RequestPart
是处理客户端到服务器的请求数据时使用的两个不同的注解,它们在多部分文件上传和表单数据处理方面有着明显的区别。
-
@RequestParam:
- 用途:主要用于处理来自查询参数(URL)或表单数据(application/x-www-form-urlencoded)的简单请求参数。
- 数据类型:通常用于处理文本类型的数据,如 String、Integer 等。
- 文件上传:虽然可以用于处理
multipart/form-data
类型的文件上传,但不是专门为此设计的。当用于文件时,通常需要将文件内容转换为字节数组或字符串。
-
@RequestPart:
- 用途:专门用于处理
multipart/form-data
请求,即文件上传请求。 - 数据类型:可以处理复杂对象,如
MultipartFile
或用户自定义的对象。它允许直接将请求的一部分映射到一个对象上,这在处理文件上传时非常有用。 - 文件上传:是处理
multipart/form-data
中文件的理想选择,直接支持MultipartFile
类型,可以很容易地访问上传的文件。
- 用途:专门用于处理