TypeScript单次JSON.stringify提交时Java控制器RequestBody接收为null如何设置参数类型
问题根因
你当前接口将@RequestBody参数定义为String类型,Spring MVC默认会对Content-Type: application/json的请求执行JSON反序列化:
- 前端单次
JSON.stringify提交的是标准JSON对象结构,Spring无法将JSON对象直接反序列化为普通字符串,因此注入null - 两次
JSON.stringify后实际提交的是JSON字符串类型值,刚好匹配String参数的反序列化规则,因此可以正常接收
解决方案
方案1(最推荐):自定义DTO类接收参数
按照请求JSON的结构定义对应的Java实体类,Spring会自动完成反序列化,不需要手动解析JSON:
// 内层账单类型实体 public class BillType { private Boolean INTAKE; // 补全Getter、Setter方法 } // 外层过滤条件实体 public class FilterParam { private BillType billType; // 补全Getter、Setter方法 }
修改Controller接口参数:
@PostMapping("/filters") public ResponseEntity<StatsDTO> listWithFilter( @RequestBody(required = false) FilterParam filter ) { // 直接调用filter对象的Getter方法就能取值,无需自行解析JSON }
前端适配:直接传过滤对象即可,Angular的HttpClient会自动完成序列化,甚至不需要手动调用JSON.stringify:
return this.http .post<Page<ClinAssistReferral>>(fullUrl, filters, { headers })
方案2:用Jackson的JsonNode接收(无需自定义实体)
如果不想额外写DTO类,可以直接使用Jackson自带的JsonNode类型接收,直接读取属性值:
import com.fasterxml.jackson.databind.JsonNode; @PostMapping("/filters") public ResponseEntity<StatsDTO> listWithFilter( @RequestBody(required = false) JsonNode filter ) { // 示例取值:filter.get("billType").get("INTAKE").asBoolean() }
方案3:用Map接收(无需自定义实体)
也可以用泛型Map接收嵌套结构的JSON参数:
@PostMapping("/filters") public ResponseEntity<StatsDTO> listWithFilter( @RequestBody(required = false) Map<String, Object> filter ) { Map<String, Boolean> billType = (Map<String, Boolean>) filter.get("billType"); Boolean intake = billType.get("INTAKE"); }
额外说明
你之前尝试org.json.JsonObject无效的原因是Spring默认的JSON消息转换器基于Jackson实现,默认不支持org.json包下的类型,需要额外配置对应转换器才能生效,性价比低,不推荐使用。
内容的提问来源于stack exchange,提问作者VictorGram
相关产品推荐
相关产品推荐

