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

如何在Spring Boot请求对象中传递Enum数据,解决POST请求Bad Request错误

问题根因

你在Days枚举上添加了@JsonFormat(shape = JsonFormat.Shape.OBJECT)注解,仅配置了枚举序列化时输出为JSON对象,但Jackson默认没有提供对应结构的反序列化逻辑,所以收到前端传入的day对象时无法转换为Days枚举实例,触发400 Bad Request错误。

解决方案

方案1:在枚举内添加@JsonCreator注解(最简便)

直接在Days枚举类中添加静态构造方法,标记为Jackson的反序列化入口,根据传入的key匹配对应枚举即可,代码示例:

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Days {
    // 原有枚举值、属性、getter保持不变
    MONDAY(1,"Monday"), TUESDAY(2,"Tuesday"),THURSDAY(4,"Thursday"), FRIDAY(5,"Friday"), SATURDAY(6,"Saturday"), 
    SUNDAY(7,"Sunday");
    
    private final Integer key;
    private final String value;

    Days(Integer key, String value) {
        this.key = key;
        this.value = value;
    }

    public Integer getKey() {
        return key;
    }

    public String getValue() {
        return value;
    }

    // 新增反序列化入口
    @JsonCreator
    public static Days getItemByKey(Map<String, Object> params) {
        Integer key = (Integer) params.get("key");
        for (Days day : Days.values()) {
            if (day.getKey().equals(key)) {
                return day;
            }
        }
        throw new IllegalArgumentException("非法的day参数:" + params);
    }
}

Jackson会自动识别@JsonCreator标记的方法作为反序列化入口,接收传入的JSON对象转换为Map后匹配枚举,不需要额外新增其他类。

方案2:自定义全局反序列化器

如果多个枚举都有类似需求,可以统一实现反序列化逻辑,步骤如下:

  1. 自定义反序列化器
public class DaysDeserializer extends StdDeserializer<Days> {
    public DaysDeserializer() {
        super(Days.class);
    }

    @Override
    public Days deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
        JsonNode node = p.getCodec().readTree(p);
        int key = node.get("key").asInt();
        for (Days day : Days.values()) {
            if (day.getKey() == key) {
                return day;
            }
        }
        throw new IllegalArgumentException("非法的day值:" + key);
    }
}
  1. 在Days枚举上绑定反序列化器
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
@JsonDeserialize(using = DaysDeserializer.class)
public enum Days {
    // 原有代码保持不变
}

补充可选方案

如果愿意调整前端传参逻辑,也可以将请求体中的day字段改为枚举名"MONDAY"或者key值1,同时调整枚举的反序列化配置即可,不过这种方式需要修改前端调用逻辑,适配成本高于上述两种后端适配方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:24:03