Spring REST控制器解析jQuery Ajax提交JSON数组为空问题排查
解决Spring Boot接收JSON数组时的空指针问题
你的问题核心在于前后端数据传输格式不匹配,再加上后端接口配置和DTO定义的几个细节错误,导致types数组无法被正确解析。下面一步步帮你修正:
1. 修正前端Ajax请求的关键配置
你的前端代码缺少了两个重要配置,导致发送的JSON数据无法被后端正确识别:
var url = "http://localhost:8080/backend/save"; // 注意路径要和后端接口一致 $.ajax({ url: url, type: 'post', contentType: 'application/json', // 必须指定,告诉后端请求体是JSON格式 data: JSON.stringify(requestJson), // 把JS对象转为标准JSON字符串 success: function( data, textStatus, jQxhr ){ console.log(data); }, error: function( jqXhr, textStatus, errorThrown ){ console.log( errorThrown ); } });
如果你的requestJson已经是JSON字符串,就不需要JSON.stringify,但通常从表单构建的是JS对象,这一步不能省。
2. 修改后端接口的接收配置
你的控制器方法配置完全错配了数据格式,需要调整两个点:
import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; // ... @RequestMapping( value = "/save", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, // 改为接收JSON格式 produces = MediaType.APPLICATION_JSON_VALUE // 可选,若返回JSON则加上 ) public Map<String, List<String>> createSot(@Valid @RequestBody MyRequestDTO myRequestDTO) { System.out.println(myRequestDTO.getId()); System.out.println(myRequestDTO.getDomain()); String[] types = myRequestDTO.getTypes(); if(types != null) { // 先做非空判断,避免空指针 for(String e: types) { System.out.println("type: " + e); } } // ... 你的其他逻辑 }
核心要点:必须加上@RequestBody注解,它会告诉Spring从请求体里解析JSON数据到DTO对象中;没有这个注解,Spring会尝试从URL参数里取值,自然拿不到数组。
3. 修正MyRequestDTO的字段定义
你的DTO有两处明显错误,导致字段映射失败:
import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; public class MyRequestDTO { @JsonProperty("id") // 补充示例JSON里的id字段 private String id; @JsonProperty("domain") private String domain; @JsonProperty("types") // 这里之前写的是"type"(单数),和JSON的"types"(复数)不匹配! private String[] types; // 也可以用List<String> types; Spring两种类型都支持解析 // 补充示例JSON里的details字段(如果需要接收的话) @JsonProperty("details") private List<DetailDTO> details; // 必须生成所有字段的getter和setter方法!Spring依赖这些方法赋值 public String getId() { return id; } public void setId(String id) { this.id = id; } public String getDomain() { return domain; } public void setDomain(String domain) { this.domain = domain; } public String[] getTypes() { return types; } public void setTypes(String[] types) { this.types = types; } public List<DetailDTO> getDetails() { return details; } public void setDetails(List<DetailDTO> details) { this.details = details; } // 嵌套DTO定义,对应示例JSON里的details结构 public static class DetailDTO { @JsonProperty("military") private MilitaryDTO military; @JsonProperty("commercial") private CommercialDTO commercial; // getter和setter public MilitaryDTO getMilitary() { return military; } public void setMilitary(MilitaryDTO military) { this.military = military; } public CommercialDTO getCommercial() { return commercial; } public void setCommercial(CommercialDTO commercial) { this.commercial = commercial; } public static class MilitaryDTO { private String name; private String country; // getter和setter public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } } public static class CommercialDTO { private String name; private String country; // getter和setter public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } } } }
重点纠正:@JsonProperty的参数必须和JSON里的键名完全一致,你之前把types写成了type,这是导致字段无法映射的直接原因。
4. 额外检查项
- 确保Spring Boot项目的
spring-boot-starter-web依赖已引入(默认包含Jackson JSON解析库,无需额外添加) - 可以先用Postman直接发送JSON请求测试后端接口,排除前端代码的干扰
按照以上步骤修改后,types数组就能被正确解析,空指针问题也会解决。
内容的提问来源于stack exchange,提问作者reiley
相关产品推荐
相关产品推荐

