Angular9上传带MultipartFile的对象列表到Spring Boot返回415错误如何解决
问题解决方案
错误根源
- 核心错误1:控制器使用
@RequestBody接收multipart/form-data类型请求,@RequestBody仅用于解析JSON/XML等文本类型请求体,无法处理文件上传的multipart格式,直接触发415错误。 - 错误2:前端FormData拼接格式不符合Spring参数绑定规则,平行的
description[]和file[]数组无法自动映射为List<FooRequestDTO>结构。
修改步骤
1. 后端代码修改
两种可选方案,推荐方案二兼容性更高:
方案A:直接绑定对象列表
把@RequestBody替换为@ModelAttribute,Spring会自动按参数名匹配绑定multipart中的字段:
@PostMapping(value = "/foo", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) @ResponseBody public void upload(@ModelAttribute List<FooRequestDTO> fooRequestDTOList) { // 原有业务逻辑 }
方案B:分开接收字段后手动组装(兼容性更好,不易出绑定问题)
直接接收两个平行列表,手动拼接为DTO列表:
@PostMapping(value = "/foo", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) @ResponseBody public void upload(@RequestParam("description") List<String> descriptions, @RequestParam("file") List<MultipartFile> files) { List<FooRequestDTO> fooRequestDTOList = new ArrayList<>(); for (int i = 0; i < descriptions.size(); i++) { FooRequestDTO dto = new FooRequestDTO(); dto.setDescription(descriptions.get(i)); dto.setFile(files.get(i)); fooRequestDTOList.add(dto); } // 原有业务逻辑 }
2. 前端代码修改
如果使用方案A,需要按索引拼接FormData字段:
upload(files: FileInfo[]): Observable<void> { const formData = new FormData(); for (let i = 0; i < files.length; i++) { formData.append(`fooRequestDTOList[${i}].description`, files[i].description); formData.append(`fooRequestDTOList[${i}].file`, files[i].file); } // 注意:不要手动设置Content-Type请求头,浏览器会自动生成带boundary的正确值 return this.http.post<void>(`/foo`, formData); }
如果使用方案B,直接拼接两个数组即可:
upload(files: FileInfo[]): Observable<void> { const formData = new FormData(); for (var i = 0; i < files.length;i++) { formData.append(`description`, files[i].description); formData.append(`file`, files[i].file); } return this.http.post<void>(`/foo`, formData); }
3. 可选校验
确认Spring Boot配置文件中multipart功能已开启(默认是开启状态,无特殊配置不需要修改):
spring.servlet.multipart.enabled=true
内容的提问来源于stack exchange,提问作者Seldo97
相关产品推荐
相关产品推荐

