@RequestPart解决同时上传文件和传递参数问题

@RequestBody和@RequestParam和@RequestPart使用场景

1.@RequestBody

使用此注解接收参数时,适用于请求体格式为 application/json,只能用对象接收.

2.@RequestParam

接收的参数是来自HTTP 请求体 或 请求url 的QueryString中只能用来接收基本数据类型String 或者MultipartFile类型,不能同时接收请求体中非String(json)和MultipartFile两种类型同传的 form-data 请求体.

3.@RequestPart

可以同时上传文件和json(任意)两种格式的form-data请求体.

@RequestParam和@RequestPart的区别

@RequestPart

@RequestPart 这个注解用在multipart/form-data表单提交请求的方法上。
支持的请求方法的方式MultipartFile,属于Spring的MultipartResolver类。这个请求是通过http协议传输的。

@RequestParam

@RequestParam支持application/json,也同样支持multipart/form-data请求。

区别

当请求方法的请求参数类型不是StringMultipartFile / Part时,而是复杂的请求域时,@RequestParam 依赖Converter or PropertyEditor进行数据解析, RequestPart参考 ‘Content-Type’ header,依赖HttpMessageConverters 进行数据解析

当请求为multipart/form-data时,@RequestParam只能接收String类型的name-value值,@RequestPart可以接收复杂的请求域(像json、xml);@RequestParam 依赖Converter or PropertyEditor进行数据解析, @RequestPart参考'Content-Type' header,依赖HttpMessageConverters进行数据解析。

前台请求:

  • jsonData为Person对象的json字符串
  • uploadFile为上传的图片

前端代码参考 VUE

1
2
3
4
5
6
7
8
9
10
11
12
let formData = new FormData();
formData.append("fileName", "文件名");
formData.append('stream', this.file);
// formData.append("fileTemplateConfs", new Blob([JSON.stringify({"title": "测试标题", "type": 3})], {type: "application/json"}));
console.log(JSON.stringify(fileData.fileTemplateConfs))
formData.append("fileTemplateConfs", new Blob([JSON.stringify(fileData.fileTemplateConfs)], {type: "application/json"}));
axios.post(`http://0.0.0.0:8082/test`, formData, {headers: {'Content-Type': 'multipart/form-data'}})
.then(response => {

}).catch(() => {
});

后台接收:

@RequestPart可以将jsonData的json数据转换为Person对象

1
2
3
4
5
6
7
8
9

@RequestMapping("jsonDataAndUploadFile")
@ResponseBody
public String jsonDataAndUploadFile(@RequestPart("uploadFile") MultiPartFile uploadFile,
@RequestPart("jsonData") Person person) {
StringBuilder sb = new StringBuilder();
sb.append(uploadFile.getOriginalFilename()).append(";;;"));
return person.toString() + ":::" + sb.toString();
}

@RequestParam对于jsonData的json数据只能用String字符串来接收

1
2
3
4
5
6
7
8
9

@RequestMapping("jsonDataAndUploadFile")
@ResponseBody
public String jsonDataAndUploadFile(@RequestPart("uploadFile") MultiPartFile uploadFile,
@RequestParam("josnData") String jsonData) {
StringBuilder sb = new StringBuilder();
sb.append(uploadFile.getOriginalFilename()).append(";;;"));
return person.toString() + ":::" + sb.toString();
}

总结

当请求头中指定Content-Type:multipart/form-data时,传递的json参数,@RequestPart注解可以用对象来接收,@RequestParam只能用字符串接收