在使用MultipartFile
接收上传的文件时,一般会有接收其他请求参数的需求
- 当请求参数过多时,通常情况下会将请求参数封装为
body
上传,文件用单独的 MultipartFile 接收,但是这样写后端一直无法接收成功
问题
@PostMapping("/save")
public Result<?> pushMoment(HttpServletRequest request,
@RequestBody ContentVo contentVo,
@RequestParam(value = "contentParam") MultipartFile contentParam
//...
}
HTTP请求分为了消息头和消息体,头信息里面的Content-Type字段定义了消息体的请求格式,接口里面声明 @RequestBody 的参数只能设置为 "Content-Type: application/json",而 MultipartFile 参数只能设置为"Content-Type: multipart/form-data",上述两种格式并不是兼容的,那问题就来了,前端请求的时候 Content-Type 怎么设置,无论哪种格式都是错的。
body
最终不能和MultipartFile
同时存在
解决方案
前端统一格式"Content-Type: multipart/form-data",结构体在前端传递的时候统一转成json字符串,后端接收以后用Gson转成结构体
@PostMapping("/save")
public Result<?> pushMoment(@RequestPart MultipartFile fileUrl,@RequestParam(value = "contentParam") String contentParam ) {
log.info("拿到的文件---> ={}",fileUrl.getOriginalFilename());
Gson gson = new Gson();
ContentUpload contentUpload = gson.fromJson(contentParam, ContentUpload.class);
}
<body>
<input id="file" type="file"/>
<br>
<button>post 请求</button>
<script>
const btns = document.querySelectorAll("button");
let contentUpload = {
//....
};
let a = JSON.stringify(contentUpload)//将对象转为 JSON
console.log(a);
btns[0].onclick = () => {
const file = document.getElementById("file").files[0];
console.log(file)
let fileUrl = new FormData();
fileUrl.append("fileUrl", file, file.name);
axios({
//请求类型
method: 'POST',
//URL
url: 'http://localhost:9999/content/save',
headers: {
"Content-Type": "multipart/form-data;boundary=" + new Date().getTime()
},
data: fileUrl,//上传的文件
params: {
contentParam: a
}
}).then(res => {
console.log(res)
})
}
</script>
</body>