@JsonCreator 注解详解——从枚举反序列化说起

@JsonCreator 注解详解------从枚举反序列化说起

一、问题的起源

先看这段实际代码:

java 复制代码
public enum SectionType implements BaseEnum {
    VIDEO(1, "视频"),
    EXAM(2, "考试"),
    ;
	@JsonValue
    @EnumValue
    int value;
    String desc;

    SectionType(int value, String desc) {
        this.value = value;
        this.desc = desc;
    }

    @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
    public static SectionType of(Integer value){
        if (value == null) return null;
        for (SectionType status : values()) {
            if (status.equalsValue(value)) return status;
        }
        return null;
    }
}

前端传数字 1,后端自动变成 VIDEO 枚举------这个"自动变"的背后,就是 @JsonCreator 在起作用。


二、为什么需要它?

默认情况下的问题

没有这个注解时,Jackson 反序列化枚举默认用的是枚举名

json 复制代码
// 前端只能这么传
{ "type": "VIDEO" }    ✅ 能解析成 SectionType.VIDEO
{ "type": "video" }    ❌ 报错(大小写不匹配)
{ "type": 1 }          ❌ 报错(类型不匹配)

但实际开发中,前端更习惯传数字(比如 1 表示视频、2 表示考试),或者数据库里存的就是数字。所以需要告诉 Jackson:"别用枚举名来匹配,按我自定义的方法来。"


三、@JsonCreator 的两个核心模式

DELEGATING(委托模式)------ 整体传入

java 复制代码
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static SectionType of(Integer value) { ... }

含义:把整个 JSON 值当成一个整体,直接丢给这个方法。

复制代码
JSON 传入 1  →  Jackson 调用 of(1)  →  返回 SectionType.VIDEO
JSON 传入 2  →  Jackson 调用 of(2)  →  返回 SectionType.EXAM

形象类比:就像快递员把整个箱子递给你,你不需要当着面拆箱核对清单,自己拎到屋里打开看一眼就知道是什么东西。

PROPERTIES(属性模式)------ 拆箱核对

java 复制代码
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
public static SectionType of(int value, String desc) { ... }

含义:把 JSON 对象拆开,按属性名一一匹配到方法参数。

json 复制代码
JSON 传入 {"value":1, "desc":"视频"}  →  of(1, "视频")  →  SectionType.VIDEO

形象类比:快递员让你当面拆箱,拿着清单逐项打勾:"value 项写的是1哈,desc 项写的是视频哈,确认无误,签收!"

总结区别

场景 DELEGATING PROPERTIES
JSON 格式 单个值:1 完整对象:{"value":1, "desc":"视频"}
方法参数 一个参数 多个参数
适合 前端传数字/字符串表示枚举 前端传完整对象

四、和 @JsonValue 是"双向通道"

别忘了这个枚举里还有另一个注解:

java 复制代码
@JsonValue    // 序列化时告诉 Jackson 用这个字段
int value;

它俩的关系就像"一去一回":

复制代码
@JsonValue(枚举 → JSON)
SectionType.VIDEO  ────────────────→  数字 1

@JsonCreator(JSON → 枚举)
数字 1  ────────────────→  SectionType.VIDEO
  • @JsonValue :枚举转 JSON 时,输出 value(1 或 2),而不是枚举名字"VIDEO"
  • @JsonCreator :JSON 转枚举时,用 of() 方法把数字还原成对应枚举

两者配合,前端和数据库全程只跟数字打交道,完全不用关心枚举的 Java 类名是什么。


五、DELEGATING 底层原理简述

Jackson 在反序列化时的大致流程:

  1. 读取到 JSON 中的值(比如 1
  2. 检查目标类型 SectionType 是否有 @JsonCreator 注解
  3. 发现模式是 DELEGATING,直接把 1 作为参数调用 of(1)
  4. of() 方法遍历枚举值,找到 value=1 的枚举 → 返回 VIDEO

如果用 PROPERTIES,第 3 步就变成:先把 JSON 解析成 TokenBuffer,然后按参数名匹配绑定。


六、总结

注解/模式 方向 一句话
@JsonValue 枚举 → JSON 序列化时改用哪个字段输出
@JsonCreator JSON → 枚举 反序列化时调用哪个方法
DELEGATING 单值传入 适合前端只传一个数字/字符串
PROPERTIES 属性匹配 适合前端传完整对象需要拆开绑定

一句话核心@JsonCreator(mode = DELEGATING) 相当于给 Jackson 装了一个"数字 ↔ 枚举"的翻译器------前端传 1,Jackson 自动找 of(1) 翻译成 VIDEO,全程不需要你写繁琐的 if-else 转换代码。


如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、转发!

有任何问题或建议,欢迎在评论区留言交流!

相关推荐
咖啡八杯7 小时前
GoF设计模式——解释器模式
java·后端·spring·设计模式
糖果店的幽灵7 小时前
【DeepAgents 从入门到精通】Context Management 上下文管理
java·人工智能·后端·spring·中间件·langgraph·deepagents
钱六两13 小时前
#3、SpringAI 接入deepSeek大模型(喂饭版)
java·spring boot·ai编程
Suhan4213 小时前
IDEA 设置启动参数和环境变量
spring boot·spring·编辑器·idea
null_1714 小时前
IntelliJ IDEA 极致流畅配置方案:Ultra 9 285K + 64GB 内存实测
java·ide·intellij-idea
記億揺晃着的那天16 小时前
NAS + Tailscale + WebDAV:安全对接云服务器 Spring Boot
spring boot·tailscale·nas·webdav
橘子海全栈攻城狮17 小时前
【最新源码】基于SpringBoot + Vue的超市管理系统的设计与实现D002
java·开发语言·vue.js·spring boot·后端·spring
空中湖17 小时前
Spring AI Function Calling 完全指南:让 AI 查数据库、调 API、发通知
数据库·人工智能·spring
风起洛阳@不良使17 小时前
spring中xml和注解开发的对比
xml·java·spring
Tenifs17 小时前
关闭 IDEA 的英文单词拼写检查
java·intellij-idea