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

使用Postman向Spring Boot发送包含枚举数组的请求时收到Null值问题(附Postman请求、RequestDTO及返回eSexes空值的ENUM类ESex)

嘿,我之前也踩过Spring Boot接收枚举数组为null的坑,咱们一步步来排查和解决它!

先把问题场景理清楚

假设你的代码和请求大概是这样的(如果和你的实际情况有出入,你可以调整):

1. 枚举类 ESex

public enum ESex {
    MALE, FEMALE, OTHER;
}

2. 请求DTO类

public class UserRequestDTO {
    private List<ESex> eSexes;

    // Getter & Setter
    public List<ESex> getESexes() {
        return eSexes;
    }

    public void setESexes(List<ESex> eSexes) {
        this.eSexes = eSexes;
    }
}

3. Postman请求示例

你发送的是JSON格式的POST请求,但后端接收后eSexes始终是null:

{
    "eSexes": ["MALE", "FEMALE"]
}
常见成因排查

我总结了几个最容易踩的坑,你可以挨个核对:

  • 1. 枚举反序列化规则没配置到位
    Spring Boot默认用Jackson处理JSON,它对枚举的反序列化默认是匹配枚举的name()值,但如果你的枚举有自定义value,或者全局配置了特殊的序列化规则,就可能导致解析失败,直接返回null。

  • 2. 请求参数和DTO字段名不匹配
    JSON是大小写敏感的!比如你DTO里是eSexes,但Postman里写成了esexes或者sexes,肯定绑定不上。

  • 3. Postman的请求头没设置对
    如果没把Content-Type设为application/json,Spring Boot根本不会把请求体当成JSON解析,字段自然就是null。

  • 4. DTO缺少无参构造函数
    Jackson实例化DTO时默认需要无参构造函数,如果你的DTO只有带参构造,可能会导致实例化失败,字段无法赋值。

  • 5. 枚举值大小写不匹配
    比如Postman里写的是male,但枚举类里是MALE,Jackson默认严格匹配,解析失败后可能直接让整个列表变成null(如果全局配置了忽略未知值的话)。

针对性解决方案

根据上面的原因,对应解决:

方案1:给枚举配置明确的反序列化规则

这是最常用的解决办法,分两种情况:

情况A:枚举用名称(name)匹配

在枚举类上加@JsonValue注解,明确告诉Jackson用枚举的name来序列化/反序列化:

import com.fasterxml.jackson.annotation.JsonValue;

public enum ESex {
    MALE, FEMALE, OTHER;

    @JsonValue
    public String getName() {
        return this.name();
    }
}

情况B:枚举有自定义value字段

如果你的枚举是带代码值的(比如MALE("M")),就需要同时配置@JsonValue和@JsonCreator:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

public enum ESex {
    MALE("M"), FEMALE("F"), OTHER("O");

    private final String code;

    ESex(String code) {
        this.code = code;
    }

    @JsonValue
    public String getCode() {
        return code;
    }

    // 反序列化时根据传入的字符串匹配枚举
    @JsonCreator
    public static ESex fromCode(String code) {
        for (ESex sex : ESex.values()) {
            // 可以加equalsIgnoreCase支持大小写不敏感
            if (sex.code.equals(code)) {
                return sex;
            }
        }
        throw new IllegalArgumentException("无效的性别值: " + code);
    }
}

方案2:确保请求参数和DTO字段完全匹配

如果不想严格区分大小写,或者JSON键名和DTO字段名不一样,可以用@JsonProperty注解明确绑定:

import com.fasterxml.jackson.annotation.JsonProperty;

public class UserRequestDTO {
    @JsonProperty("eSexes") // 强制绑定JSON里的"eSexes"键
    private List<ESex> eSexes;

    // Getter & Setter
}

方案3:修正Postman的请求配置

在Postman的Headers里添加:

  • Key: Content-Type
  • Value: application/json

同时确保请求体选择raw -> JSON格式,不要用form-data或x-www-form-urlencoded(如果用表单的话,枚举数组的格式是eSexes=MALE&eSexes=FEMALE,需要后端用@RequestParam接收)。

方案4:给DTO添加无参构造函数

如果你的DTO没有无参构造,一定要加上:

public class UserRequestDTO {
    private List<ESex> eSexes;

    // 无参构造函数
    public UserRequestDTO() {}

    // Getter & Setter
}

方案5:统一枚举值的大小写

要么把Postman里的枚举值改成和枚举类一致的大小写,要么在@JsonCreator方法里做忽略大小写的判断(比如方案1的情况B里把equals改成equalsIgnoreCase)。

验证是否解决

修改后,在后端接口里加个日志打印,看看接收情况:

@RestController
@RequestMapping("/users")
public class UserController {
    @PostMapping
    public ResponseEntity<String> createUser(@RequestBody UserRequestDTO requestDTO) {
        System.out.println("接收的性别列表: " + requestDTO.getESexes());
        return ResponseEntity.ok("请求成功");
    }
}

如果日志里能输出[MALE, FEMALE],说明问题搞定啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 20:42:35