React上传图片至Spring报错MultipartException:请求非多部分请求
问题排查与解决方法
1. 检查Axios请求的Content-Type设置
不要手动设置Content-Type: multipart/form-data,浏览器会自动生成包含boundary的正确请求头。手动设置会丢失boundary参数,导致Spring无法识别为多部分请求。
错误写法:
axios.post('/api/assets', formData, { headers: { 'Content-Type': 'multipart/form-data' // 错误:手动设置丢失boundary } })
正确写法:
axios.post('/api/assets', formData) // 或显式让浏览器自动处理请求头 axios.post('/api/assets', formData, { headers: { 'Content-Type': undefined } })
2. 确保FormData构建正确
必须用FormData对象封装所有表单数据和文件,不能直接传递JSON对象。所有字段(文本、文件)都要通过append方法添加:
const formData = new FormData(); // 添加普通文本字段 formData.append('name', assetName); formData.append('description', assetDesc); // 添加文件(file为<input type="file">获取的文件对象) formData.append('imageFile', file);
3. 修正Spring控制器的参数接收方式
不能用@RequestBody接收multipart请求,需用@RequestPart或@RequestParam分别接收实体数据和文件,建议分开接收后手动关联实体:
正确写法:
@CrossOrigin @PostMapping(value = "/assets", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity<Assets> createAsset( @RequestPart("assets") Assets assets, @RequestPart("imageFile") MultipartFile file) { // 先保存主实体Assets Assets savedAsset = assetsRepository.save(assets); // 创建Image实体并关联Asset ID Image image = new Image(); image.setAssetId(savedAsset.getId()); image.setFileName(file.getOriginalFilename()); image.setFileData(file.getBytes()); imageRepository.save(image); return ResponseEntity.ok(savedAsset); }
对应前端需将实体转为JSON字符串添加到FormData:
formData.append('assets', new Blob([JSON.stringify(assetsData)], { type: 'application/json' }));
如果不想传递JSON字符串,也可以拆分实体字段逐个append,控制器用@RequestParam接收单个字段再组装实体:
public ResponseEntity<Assets> createAsset( @RequestParam("name") String name, @RequestParam("description") String description, @RequestPart("imageFile") MultipartFile file) { Assets assets = new Assets(); assets.setName(name); assets.setDescription(description); // 后续保存逻辑... }
4. 检查Spring的Multipart配置
Spring Boot默认启用multipart支持,可显式配置确认:
在application.properties中添加:
spring.servlet.multipart.enabled=true spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=10MB
若为Spring MVC(非Boot),需手动配置MultipartResolver:
@Bean public CommonsMultipartResolver multipartResolver() { CommonsMultipartResolver resolver = new CommonsMultipartResolver(); resolver.setMaxUploadSize(10*1024*1024); // 10MB return resolver; }
5. 排除实体类关联的影响
如果Assets和Image是JPA关联关系,不要让Spring自动绑定multipart请求到关联实体。应先保存主实体Assets,再手动创建Image并设置外键ID,避免绑定过程中出现解析错误。
内容的提问来源于stack exchange,提问作者Артём Орёл
相关产品推荐
相关产品推荐

