弹簧启动控制器 - 将多部分和 JSON 上传到 DTO
2022-08-31 16:49:50
我想将表单中的文件上传到 Spring Boot API 终结点。
UI 是用 React 编写的:
export function createExpense(formData) {
return dispatch => {
axios.post(ENDPOINT,
formData,
headers: {
'Authorization': //...,
'Content-Type': 'application/json'
}
).then(({data}) => {
//...
})
.catch(({response}) => {
//...
});
};
}
_onSubmit = values => {
let formData = new FormData();
formData.append('title', values.title);
formData.append('description', values.description);
formData.append('amount', values.amount);
formData.append('image', values.image[0]);
this.props.createExpense(formData);
}
这是 java 端代码:
@RequestMapping(path = "/{groupId}", method = RequestMethod.POST)
public ExpenseSnippetGetDto create(@RequestBody ExpensePostDto expenseDto, @PathVariable long groupId, Principal principal, BindingResult result) throws IOException {
//..
}
但是我在Java方面得到了这个例外:
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;boundary=----WebKitFormBoundaryapHVvBsdZYc6j4Af;charset=UTF-8' not supported
我应该如何解决此问题?类似的API端点和JavaScript端代码已经工作。
注意
我见过一个解决方案,它建议请求正文应该有2个属性:一个是JSON部分,另一个是图像。我想看看是否有可能将其自动转换为DTO。
更新 1
客户端发送的上载负载应转换为以下 DTO:
public class ExpensePostDto extends ExpenseBaseDto {
private MultipartFile image;
private String description;
private List<Long> sharers;
}
所以你可以说它是JSON和多部分的混合体。
溶液
该问题的解决方案是在前端和后端使用:FormData
ModelAttribute
@RequestMapping(path = "/{groupId}", method = RequestMethod.POST,
consumes = {"multipart/form-data"})
public ExpenseSnippetGetDto create(@ModelAttribute ExpensePostDto expenseDto, @PathVariable long groupId, Principal principal) throws IOException {
//...
}
在前端,摆脱它应该由浏览器本身决定,并使用(标准JavaScript)。这应该可以解决问题。Content-Type
FormData