Spring Boot如何在multipart请求中接收对象列表?
问题分析与解决方案
核心原因
你的接口用@ModelAttribute接收multipart/form-data类型请求时,Spring默认只能解析表单键值对格式的参数,无法自动将JSON字符串格式的contacts参数转换成List<Contacts>对象列表,这就是报错的根本原因。另外注意你的DTO存在笔误:PartnerRequest里的List<Contact>应该改为List<Contacts>(和定义的record类型保持一致)。
解决方案1:用表单数组格式提交参数(推荐)
直接在Postman里按表单键值对的数组格式填写contacts的每个字段,Spring会自动绑定到List<Contacts>:
- 添加参数:
contacts[0].name,值填testName - 添加参数:
contacts[0].email,值填testEmail - 如果有多个联系人,继续添加
contacts[1].name、contacts[1].email以此类推
这种方式符合@ModelAttribute的默认解析规则,不需要额外配置。
解决方案2:自定义类型转换器
如果一定要传JSON格式的contacts字符串,可以自定义转换器让Spring自动完成转换:
- 编写转换器类:
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; import java.util.List; @Component public class StringToContactsListConverter implements Converter<String, List<Contacts>> { private final ObjectMapper objectMapper; public StringToContactsListConverter(ObjectMapper objectMapper) { this.objectMapper = objectMapper; } @Override public List<Contacts> convert(String source) { try { return objectMapper.readValue(source, new TypeReference<List<Contacts>>() {}); } catch (Exception e) { throw new IllegalArgumentException("Invalid JSON format for contacts list", e); } } }
- 注册转换器到Spring MVC配置:
import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { private final StringToContactsListConverter contactsListConverter; public WebConfig(StringToContactsListConverter contactsListConverter) { this.contactsListConverter = contactsListConverter; } @Override public void addFormatters(FormatterRegistry registry) { registry.addConverter(contactsListConverter); } }
配置完成后,在Postman里直接把contacts参数的值填成[{"name": "testName", "email": "testEmail"}],Spring会自动调用转换器把JSON字符串转成List<Contacts>。
解决方案3:手动解析JSON字符串(快速临时方案)
如果不想修改配置,可以临时修改PartnerRequest的contacts字段类型为String,然后在接口方法里手动转换成列表:
修改DTO:
public record PartnerRequest( String name, MultipartFile logo, String link, String contacts // 改为String类型 ){}
接口方法里手动转换:
@PostMapping(value = "createPartner", consumes = "multipart/form-data") public ResponseEntity<String> createPartner( @ModelAttribute PartnerRequest partnerRequest, ObjectMapper objectMapper ) throws IOException { // 手动把JSON字符串转成List<Contacts> List<Contacts> contacts = objectMapper.readValue(partnerRequest.contacts(), new TypeReference<List<Contacts>>() {}); // 后续业务逻辑... return ResponseEntity.ok("Success"); }
这种方式适合快速验证,但不够优雅,建议优先用前两种方案。
内容的提问来源于stack exchange,提问作者Akari Oozora
相关产品推荐
相关产品推荐

