🎉🎉《Spring Boot实战案例合集》目前已更新186个案例,我们将持续不断的更新。文末有电子书目录。
💪💪永久更新承诺
我们郑重承诺,所有订阅合集的粉丝都将享受永久免费的后续更新服务。
💌💌如何获取
订阅我们的合集《点我订阅》,并通过私信联系我们,我们将第一时间将电子书发送给您。
环境:SpringBoot3.4.2
1. 简介
在系统开发中,JSON 作为轻量级数据交换格式被广泛应用,而枚举(Enum)作为 Java 等语言中表示固定常量集合的类型,其与 JSON 的交互处理至关重要。传统场景下,枚举序列化可能直接输出其名称(如 "MALE"),但实际业务中常需更灵活的映射,例如输出数字代码(1)或国际化描述("男")。同时,反序列化时需根据 JSON 值(如数字或字符串)精准匹配枚举实例。
本篇文章将详细介绍枚举值在序列化和反序列化过程中的核心处理机制、常见应用场景及最佳实践方案。
2.1 准备环境
定义性别枚举类
public enum Gender {UNKNOWN(0, "未知的性别"), MALE(1, "男"), FEMALE(2, "女"), UNSTATED(9, "未说明的性别");private final int code;private final String name;Gender(int code, String name) {this.code = code;this.name = name;}public int getCode() {return code ;}public String getName() {return name ;}}
定义User实体对象包括上面的枚举字段
public record User(String name, int age, Gender gender) {}
2.2 默认输出枚举值
("/users")public class UserController {public ResponseEntity<User> query() {return ResponseEntity.ok(new User("Pack_xg", 33, Gender.MALE)) ;}}
输出结果
2.3 将枚举序列化为JSON对象
当我们希望将枚举值序列化为如下格式:
{"code": 1, "name": "男"}
要输出此格式,我们可以通过如下注解进行标注枚举类:
public enum Gender {// ...}
输出结果
2.4 枚举与@JsonValue结合
控制枚举序列化输出的另一种简单方法是在 getter 方法上使用 @JsonValue 注解。该注解用于指示被注解的访问器(字段或“getter”方法[非void返回类型、无参数的方法])的值应作为该实例的单一值进行序列化,而非采用常规的收集属性值的方式。
修改枚举类如下:
public enum Gender {// ...public String getName() {return name;}}
在我们希望输出的字段上使用@JsonValue注解。
输出结果
当我们将@JsonValue使用到类中的toString时,如下:
public record User(String name, int age, Gender gender) {@JsonValuepublic String toString() {return "【name = " + this.name + ", age = " + this.age + ", gender = " + this.gender + "】";}}
输出结果
2.5 自定义枚举序列化
我们可以通过继承 StdSerializer 的方式,实现自定义的序列化方式,如下示例:
public class GenderSerializer extends StdSerializer<Gender> {public GenderSerializer() {super(Gender.class);}public GenderSerializer(Class<Gender> t) {super(t);}public void serialize(Gender value, JsonGenerator generator, SerializerProvider provider)throws IOException, JsonProcessingException {generator.writeStartObject() ;generator.writeFieldName("label") ;generator.writeString(value.name()) ;generator.writeFieldName("value") ;generator.writeNumber(value.getCode()) ;generator.writeEndObject();}}
接着修改Gender枚举类
@JsonSerialize(using = GenderSerializer.class)public enum Gender {}
输出结果
2.6 反序列化枚举
public ResponseEntity<User> save( User user) {return ResponseEntity.ok(user) ;}
默认情况
我们修改gender值为数字也同样可以,如下:
使用@JsonValue
public enum Gender {@JsonValuepublic int getCode() {return code;}}
输出结果
这时候你再换成枚举的字面量值将会报错,如下:
使用@JsonProperty
通过使用此注解,我们只是告诉Jackson将@JsonProperty的值映射到标注此值的对象。如下示例:
修改枚举类
public enum Gender {UNKNOWN(0, "未知的性别"),MALE(1, "男"),FEMALE(2, "女"),UNSTATED(9, "未说明的性别");}
输出结果
使用@JsonCreator
该注解用于将构造函数或工厂方法定义为用于实例化关联类新实例的指定方法。
修改枚举类如下:
public enum Gender {// ...public Gender fromCode(("gender") int code) {for (Gender gender : Gender.values()) {if (gender.code == code) {return gender;}}throw new IllegalArgumentException("无效的性别代码: " + code);}}
输出结果
自定义反序列化
定义反序列化类
public class GenderDeserializer extends StdDeserializer<Gender> {public GenderDeserializer() {super(Gender.class) ;}public Gender deserialize(JsonParser jsonParser, DeserializationContext ctxt)throws IOException, JsonProcessingException {int gender = jsonParser.getValueAsInt() ;for (Gender g : Gender.values()) {if (g.getCode() == gender) {return g ;}}return null;}}
修改枚举类
@JsonDeserialize(using = GenderDeserializer.class)public enum Gender {}
输出结果
不会前端技术?Spring Boot + HTMX:零JS打造SPA
Spring Boot 10个超实用扩展点,让你的项目效率飙升
告别OOM!Spring Boot 流式导出百万数据:支持MyBatis/JPA/Jdbc
性能优化!Spring Boot 使用 @QueryHints 优化数据库性能
强大!Spring Boot 通过事务感知解决数据库与缓存不一致问题
Spring Boot 通过 6 种方式实现开关功能,最后一种直接封神
Spring Boot 记录Controller接口请求日志7种方式,第六种性能极高
请一定记住!Spring Boot 执行初始化操作的 7 种王炸手段
高手必备!Spring Boot 非常实用的10个核心扩展点


