Spring+React上传图片遇MultipartException:当前请求非多部分请求
问题描述
我用Spring做后端、React做前端,尝试创建附带图片的Item。已经给添加商品详情和图片的表单设置了enctype="multipart/form-data",但仍出现Axios 500错误,Spring控制台报错:
org.springframework.web.multipart.MultipartException: Current request is not a multipart request
我创建了Items和Images两个实体类及对应控制器,前端也实现了带文件上传的模态框表单,通过Axios发送请求。控制台能获取到文件数据,但请求被服务器拒绝,请问问题出在哪里,该如何解决?
常见原因及解决办法
1. 后端未启用Multipart配置
Spring默认的文件上传解析器可能未正确启用,需要显式配置:
- 方式一:通过配置类添加MultipartResolver
@Configuration public class MultipartConfig { @Bean public MultipartResolver multipartResolver() { CommonsMultipartResolver resolver = new CommonsMultipartResolver(); resolver.setMaxUploadSize(5242880); // 设置最大上传大小(示例为5MB) return resolver; } }
- 方式二:在
application.properties中配置
spring.servlet.multipart.enabled=true spring.servlet.multipart.max-file-size=5MB spring.servlet.multipart.max-request-size=5MB
2. 前端Axios请求格式错误
即使表单设置了enctype,如果Axios没有用FormData正确封装数据,服务器依然识别不了多部分请求。正确的前端提交逻辑如下:
const handleSubmit = (e) => { e.preventDefault(); const formData = new FormData(); // 添加商品字段 formData.append('itemName', itemName); formData.append('price', price); // 添加图片文件 formData.append('imageFile', imageFile); axios.post('/api/items', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) .then(res => console.log('上传成功', res)) .catch(err => console.error('上传失败', err)); };
注意:不要手动拼接boundary参数,Axios会自动根据FormData生成正确的请求头,手动设置反而会导致服务器无法解析。
3. 后端控制器参数接收错误
控制器方法要正确匹配前端传递的参数名,确保MultipartFile和普通字段的注解使用正确:
- 直接接收参数的写法:
@PostMapping("/api/items") public ResponseEntity<Item> createItem( @RequestParam("itemName") String itemName, @RequestParam("price") Double price, @RequestParam("imageFile") MultipartFile imageFile) throws IOException { // 实例化Item和Image并关联 Item item = new Item(); item.setName(itemName); item.setPrice(price); Image image = new Image(); image.setFileName(imageFile.getOriginalFilename()); image.setContentType(imageFile.getContentType()); image.setData(imageFile.getBytes()); image.setItem(item); item.getImages().add(image); itemRepository.save(item); return ResponseEntity.ok(item); }
- 使用DTO接收的写法:
// 定义DTO类 public class ItemCreateDTO { private String itemName; private Double price; private MultipartFile imageFile; // getter、setter方法 } // 控制器方法 @PostMapping("/api/items") public ResponseEntity<Item> createItem(@ModelAttribute ItemCreateDTO dto) throws IOException { // 业务处理逻辑同上 }
4. 跨域配置未允许Multipart请求
如果前后端存在跨域,需要确保后端CORS配置允许multipart/form-data类型的请求:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:3000") // 替换为你的前端地址 .allowedMethods("GET", "POST", "PUT", "DELETE") .allowedHeaders("*") .allowCredentials(true); } }
内容的提问来源于stack exchange,提问作者Артём Орёл
相关产品推荐
相关产品推荐

