大数跨境
0
0

别再用 toString() 了!Spring Boot + Jackson 处理枚举的7种方式

别再用 toString() 了!Spring Boot + Jackson 处理枚举的7种方式 Spring全家桶实战案例
2025-10-24
0
导读:别再用 toString() 了!Spring Boot + Jackson 处理枚举的7种方式
Spring Boot 3实战案例锦集PDF电子书已更新至130篇!
图片

🎉🎉《Spring Boot实战案例合集》目前已更新186个案例,我们将持续不断的更新。文末有电子书目录。

💪💪永久更新承诺

我们郑重承诺,所有订阅合集的粉丝都将享受永久免费的后续更新服务

💌💌如何获取
订阅我们的合集点我订阅,并通过私信联系我们,我们将第一时间将电子书发送给您。

→ 现在就订阅合集

环境:SpringBoot3.4.2



1. 简介

在系统开发中,JSON 作为轻量级数据交换格式被广泛应用,而枚举(Enum)作为 Java 等语言中表示固定常量集合的类型,其与 JSON 的交互处理至关重要。传统场景下,枚举序列化可能直接输出其名称(如 "MALE"),但实际业务中常需更灵活的映射,例如输出数字代码(1)或国际化描述("男")。同时,反序列化时需根据 JSON 值(如数字或字符串)精准匹配枚举实例。

本篇文章将详细介绍枚举值在序列化和反序列化过程中的核心处理机制、常见应用场景及最佳实践方案。

2.实战案例

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 默认输出枚举值

@RestController@RequestMapping("/users")public class UserController {  @GetMapping  public ResponseEntity<Userquery() {    return ResponseEntity.ok(new User("Pack_xg"33Gender.MALE)) ;  }}

输出结果

2.3 将枚举序列化为JSON对象

当我们希望将枚举值序列化为如下格式:

{"code": 1"name""男"}

要输出此格式,我们可以通过如下注解进行标注枚举类:

@JsonFormat(shape = JsonFormat.Shape.OBJECT)public enum Gender {  // ...}

输出结果

2.4 枚举与@JsonValue结合

控制枚举序列化输出的另一种简单方法是在 getter 方法上使用 @JsonValue 注解。该注解用于指示被注解的访问器(字段或“getter”方法[非void返回类型、无参数的方法])的值应作为该实例的单一值进行序列化,而非采用常规的收集属性值的方式。

修改枚举类如下:

public enum Gender {  // ...  @JsonValue  public String getName() {    return name;  }}

在我们希望输出的字段上使用@JsonValue注解。

输出结果

当我们将@JsonValue使用到类中的toString时,如下:

public record User(String name, int age, Gender gender) {  @JsonValue  public 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 反序列化枚举

@PostMappingpublic ResponseEntity<Usersave(@RequestBody User user) {  return ResponseEntity.ok(user) ;}

默认情况

我们修改gender值为数字也同样可以,如下:

使用@JsonValue

public enum Gender {  @JsonValue  public int getCode() {    return code;  }}

输出结果

这时候你再换成枚举的字面量值将会报错,如下:

使用@JsonProperty

通过使用此注解,我们只是告诉Jackson将@JsonProperty的值映射到标注此值的对象。如下示例:

修改枚举类

public enum Gender {  @JsonProperty("unknow")  UNKNOWN(0"未知的性别"),  @JsonProperty("male")  MALE(1"男"),   @JsonProperty("female")  FEMALE(2"女"),   @JsonProperty("unknow_gender")  UNSTATED(9"未说明的性别");}

输出结果

使用@JsonCreator

该注解用于将构造函数或工厂方法定义为用于实例化关联类新实例的指定方法。

修改枚举类如下:

public enum Gender {  // ...  @JsonCreator  public Gender fromCode(@JsonProperty("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) ;  }  @Override  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 通过事务感知解决数据库与缓存不一致问题

强大!基于Map优化缓存设计

Spring Boot 通过 6 种方式实现开关功能,最后一种直接封神

Spring Boot 记录Controller接口请求日志7种方式,第六种性能极高

惊呆了!Controller接口返回值支持17种逆天类型

太实用了!MySQL强大的JSON数据类型提升查询效率

请一定记住!Spring Boot 执行初始化操作的 7 种王炸手段

高手必备!Spring Boot 非常实用的10个核心扩展点

图片
图片
图片
图片
图片
图片
图片
图片
图片

【声明】内容源于网络
0
0
Spring全家桶实战案例
Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
内容 832
粉丝 0
Spring全家桶实战案例 Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
总阅读285
粉丝0
内容832