Spring Boot REST API接收Ajax传递的含图片自定义对象列表为空问题
问题解决:Ajax传递含图片的对象列表到Spring Boot后端,列表接收为空
问题分析
核心问题有两个:一是FormData无法直接传递复杂对象数组,直接append("addressList", addressList)会把数组转成[object Object],[object Object]这类无效字符串,Spring MVC无法自动解析为List<AddressDTO>;二是你的DTO类缺少getter/setter方法,导致Spring无法完成属性绑定。
解决方案
方案一:将数组转为JSON字符串传递(推荐)
前端Ajax修改
let addressList = []; let addressDTO1 = {"city": "city1","area": "area1","pincode":"pincode1"}; let addressDTO2 = {"city": "city2","area": "area2","pincode":"pincode2"}; addressList.push(addressDTO1); addressList.push(addressDTO2); var form = $('#userDetail')[0]; var data = new FormData(form); data.append("name", "testUSer"); // 将数组转为JSON字符串后添加到FormData data.append("addressList", JSON.stringify(addressList)); // 注意:这里要传入真实的文件对象,比如通过input获取 data.append("imgFile", $('#imgFile')[0].files[0]); $.ajax({ url: "/test/saveUser", data: data, enctype: "multipart/form-data", processData: false, contentType: false, type: "POST", success: function(response) { console.log("保存成功", response); }, error : function(xhr) { console.error("保存失败", xhr); } });
后端代码调整
- 给DTO添加完整的getter/setter方法:
public class UserDTO{ private String id; private String name; private byte[] thumbNailImage; private List<AddressDTO> addressList; // 所有属性的getter和setter public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public byte[] getThumbNailImage() { return thumbNailImage; } public void setThumbNailImage(byte[] thumbNailImage) { this.thumbNailImage = thumbNailImage; } public List<AddressDTO> getAddressList() { return addressList; } public void setAddressList(List<AddressDTO> addressList) { this.addressList = addressList; } } public class AddressDTO{ private String id; private String city; private String area; private String pincode; // 所有属性的getter和setter public String getId() { return id; } public void setId(String id) { this.id = id; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getArea() { return area; } public void setArea(String area) { this.area = area; } public String getPincode() { return pincode; } public void setPincode(String pincode) { this.pincode = pincode; } }
- Controller中手动解析JSON字符串:
import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.List; @PostMapping(value = "/test/saveUser", consumes = "multipart/form-data") @ResponseBody public String saveMission(@ModelAttribute UserDTO userDTO, @RequestParam(value = "imgFile", required = false) MultipartFile file, @RequestParam("addressList") String addressListJson) throws Exception { // 使用Jackson解析JSON字符串为List<AddressDTO> ObjectMapper objectMapper = new ObjectMapper(); List<AddressDTO> addressList = objectMapper.readValue( addressListJson, objectMapper.getTypeFactory().constructCollectionType(List.class, AddressDTO.class) ); userDTO.setAddressList(addressList); // 调用业务逻辑保存数据 return "success"; }
方案二:按索引逐个传递列表项属性
如果不想转JSON,可以通过索引形式拆分每个对象的属性,让Spring MVC自动绑定:
前端Ajax修改
let addressList = []; let addressDTO1 = {"city": "city1","area": "area1","pincode":"pincode1"}; let addressDTO2 = {"city": "city2","area": "area2","pincode":"pincode2"}; addressList.push(addressDTO1); addressList.push(addressDTO2); var form = $('#userDetail')[0]; var data = new FormData(form); data.append("name", "testUSer"); // 逐个添加列表项的属性,用索引标记层级 addressList.forEach((item, index) => { data.append(`addressList[${index}].city`, item.city); data.append(`addressList[${index}].area`, item.area); data.append(`addressList[${index}].pincode`, item.pincode); }); data.append("imgFile", $('#imgFile')[0].files[0]); $.ajax({ url: "/test/saveUser", data: data, enctype: "multipart/form-data", processData: false, contentType: false, type: "POST", success: function(response) { console.log("保存成功", response); }, error : function(xhr) { console.error("保存失败", xhr); } });
后端Controller调整
只需确保DTO有getter/setter,参数添加@ModelAttribute即可:
@PostMapping(value = "/test/saveUser", consumes = "multipart/form-data") @ResponseBody public String saveMission(@ModelAttribute UserDTO userDTO, @RequestParam(value = "imgFile", required = false) MultipartFile file) throws Exception { // 此时userDTO的addressList已自动绑定 // 调用业务逻辑保存数据 return "success"; }
关键注意事项
- 必须给DTO添加getter/setter:Spring MVC依赖这些方法完成属性注入,没有的话无法绑定任何属性。
- FormData传递复杂对象的限制:直接传递数组或对象会被转为无效字符串,必须转JSON或拆分属性传递。
- 文件对象的正确性:确保
imgFile传递的是真实的File对象,而非字符串或其他类型。
内容的提问来源于stack exchange,提问作者Yogesh
相关产品推荐
相关产品推荐

