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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 06:15:06