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

如何在REST API的RequestBody中排除null字段值?

解决Spring Boot PATCH接口请求体null字段不被忽略的问题

问题原因

你添加的@JsonInclude(JsonInclude.Include.NON_NULL)注解仅在**序列化(将POJO转为JSON响应)时生效,控制返回结果不包含null字段;但在反序列化(将请求JSON转为POJO)**过程中,这个注解不会起作用,所以请求里的productNo: null依然会被赋值到POJO的对应字段中。

解决方案

方案1:字段级配置忽略反序列化null值

给需要忽略null的字段添加@JsonSetter(nulls = Nulls.SKIP)注解,Jackson在反序列化时遇到null值就不会设置该字段,保持字段原有默认值:

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.deser.std.Nulls;
import lombok.Data;

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Product {
    private String name;
    private String productId;

    @JsonSetter(nulls = Nulls.SKIP)
    private String productNo;

    private String targetArea;
    private int minimumQuantity;
    private double buyingPrice;
    private int quantity;
    private String selfStatus;
    private double sellingPrice;
}

方案2:全局配置反序列化忽略null值

如果希望所有POJO在反序列化时都忽略null字段,可以添加全局Jackson配置:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.databind.deser.std.Nulls;

@Configuration
public class JacksonConfig {
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> builder.postConfigurer(mapper -> {
            // 设置全局反序列化时跳过null值的赋值
            mapper.setDefaultSetterInfo(JsonSetter.Value.forContentNulls(Nulls.SKIP));
        });
    }
}

方案3:针对PATCH请求的优化方案(推荐)

PATCH接口是部分更新,更适合用Map<String, Object>接收请求体,或者创建专用的更新DTO,手动处理非null字段,避免基本类型默认值的干扰(比如int类型的minimumQuantity默认是0,可能会被误更新):

@RequestMapping(value = "/update-product/{product-id}", method = RequestMethod.PATCH)
public ResponseEntity<Product> updateProduct(@RequestBody Map<String, Object> updateParams, @PathVariable("product-id") String productId) {
    // 1. 从数据库查询原产品信息
    Product originalProduct = productService.getById(productId);
    // 2. 遍历更新参数,只处理非null的字段
    updateParams.forEach((key, value) -> {
        if (value == null) return;
        switch (key) {
            case "name":
                originalProduct.setName((String) value);
                break;
            case "targetArea":
                originalProduct.setTargetArea((String) value);
                break;
            case "productNo":
                originalProduct.setProductNo((String) value);
                break;
            // 其他字段按需处理
        }
    });
    // 3. 保存并返回更新后的产品
    Product updatedProduct = productService.save(originalProduct);
    return new ResponseEntity<>(updatedProduct, HttpStatus.OK);
}

额外注意事项

  1. 控制器代码中@PathVariable (“product-id”)使用了中文引号,会导致编译错误,需改为英文引号:@PathVariable("product-id")
  2. 测试用的JSON请求中“targetArea: “12345”的引号是中文的,修正为:
{
    "targetArea": "12345",
    "name": "Bucket",
    "productNo": null
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:10:55