如何在枚举为只读时让Jackson将枚举常量序列化为小写值?
问题背景
由于Swagger UI存在相关问题,我们需要将枚举类型序列化为小写蛇形字符串(如INSTANCE_ONE转为instance_one),但由于没有SomeClass的修改权限,无法直接在枚举类上添加@JsonValue注解,希望通过配置ObjectMapper来实现需求。
原场景的最小可复现代码如下:
原枚举与实体类
package com.example.dynamicgateway.misc; import lombok.Getter; import lombok.NoArgsConstructor; @NoArgsConstructor @Getter class SomeClass { SomeEnum someEnumProperty = SomeEnum.INSTANCE_ONE; enum SomeEnum { INSTANCE_ONE, INSTANCE_TWO; } }
测试代码
package com.example.dynamicgateway.misc; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.SneakyThrows; import org.junit.jupiter.api.Test; public class GenericTest { @Test @SneakyThrows void test() { ObjectMapper objectMapper = new ObjectMapper(); SomeClass someClass = new SomeClass(); String serializedSomeClass = objectMapper.writeValueAsString(someClass); System.out.println(serializedSomeClass); } }
默认输出为:
{"someEnumProperty":"INSTANCE_ONE"}
解决方案
可以通过自定义枚举序列化器并注册到ObjectMapper的方式实现,无需修改原类代码。
步骤1:自定义枚举序列化器
创建一个通用的枚举序列化器,将枚举名称转为小写格式:
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; public class LowerCaseEnumSerializer extends JsonSerializer<Enum<?>> { @Override public void serialize(Enum<?> value, JsonGenerator gen, SerializerProvider serializers) throws IOException { // 将枚举名称转为小写(INSTANCE_ONE → instance_one) gen.writeString(value.name().toLowerCase()); } }
步骤2:注册序列化器到ObjectMapper
在测试代码中,将自定义序列化器注册到ObjectMapper,指定针对SomeEnum生效:
package com.example.dynamicgateway.misc; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import lombok.SneakyThrows; import org.junit.jupiter.api.Test; public class GenericTest { @Test @SneakyThrows void test() { ObjectMapper objectMapper = new ObjectMapper(); // 创建模块并注册自定义序列化器 SimpleModule module = new SimpleModule(); module.addSerializer(SomeClass.SomeEnum.class, new LowerCaseEnumSerializer()); objectMapper.registerModule(module); SomeClass someClass = new SomeClass(); String serializedSomeClass = objectMapper.writeValueAsString(someClass); System.out.println(serializedSomeClass); } }
输出结果
{"someEnumProperty":"instance_one"}
扩展:对所有枚举生效
如果需要让项目中所有枚举都采用这种序列化规则,可以修改注册方式,不指定具体枚举类:
module.addSerializer(Enum.class, new LowerCaseEnumSerializer());
这样所有枚举类型在序列化时都会自动转为小写名称格式。
内容的提问来源于stack exchange,提问作者Sergey Zolotarev
相关产品推荐
相关产品推荐

