You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
    }
});

后端代码调整

  1. 给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; }
}
  1. 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";
}

关键注意事项

  1. 必须给DTO添加getter/setter:Spring MVC依赖这些方法完成属性注入,没有的话无法绑定任何属性。
  2. FormData传递复杂对象的限制:直接传递数组或对象会被转为无效字符串,必须转JSON或拆分属性传递。
  3. 文件对象的正确性:确保imgFile传递的是真实的File对象,而非字符串或其他类型。

内容的提问来源于stack exchange,提问作者Yogesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 21:17:56