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

如何用Jackson @JsonSerialize实现通用枚举转Integer序列化?

实现通用的枚举序列化器(Integer转枚举)

你遇到的问题根源是Java泛型擦除特性——编译后泛型参数会被抹除,Jackson无法在运行时获取泛型传递的枚举类型,因此直接用泛型的方式不可行。下面是一套通用解决方案,只需要一个序列化器就能适配所有符合规范的枚举类:

步骤1:定义通用枚举接口

让所有需要转换的枚举类实现这个接口,统一code的获取逻辑:

public interface CodeEnum {
    Integer getCode();
}

步骤2:改造现有枚举类

让你的StatusEnum(以及其他需要转换的枚举类)实现上述接口:

public enum StatusEnum implements CodeEnum {
    ON(1),
    OFF(0);

    private final Integer code;

    StatusEnum(Integer code) {
        this.code = code;
    }

    @Override
    public Integer getCode() {
        return code;
    }
}

步骤3:自定义注解传递枚举类型

通过自定义注解,明确指定当前字段对应的目标枚举类:

import java.lang.annotation.*;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnumSerialize {
    // 指定要转换的枚举类
    Class<? extends Enum<? extends CodeEnum>> value();
}

步骤4:编写通用序列化器

这个序列化器会从字段的注解中获取枚举类,再根据Integer值匹配对应的枚举实例:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.lang.reflect.Field;

public class GenericEnumSerializer extends JsonSerializer<Integer> {

    @Override
    public void serialize(Integer value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        if (value == null) {
            jsonGenerator.writeNull();
            return;
        }

        try {
            // 获取当前序列化的字段
            Field field = serializerProvider.getContextualType().getRawClass()
                    .getDeclaredField(serializerProvider.getPropertyName());
            EnumSerialize enumAnnotation = field.getAnnotation(EnumSerialize.class);

            if (enumAnnotation == null) {
                jsonGenerator.writeNull();
                return;
            }

            // 获取枚举类的所有实例
            Class<? extends Enum<? extends CodeEnum>> enumClass = enumAnnotation.value();
            Enum<? extends CodeEnum>[] enumConstants = enumClass.getEnumConstants();

            // 匹配对应code的枚举
            for (Enum<? extends CodeEnum> enumInstance : enumConstants) {
                CodeEnum codeEnum = (CodeEnum) enumInstance;
                if (codeEnum.getCode().equals(value)) {
                    jsonGenerator.writeObject(enumInstance);
                    return;
                }
            }

            // 未匹配到对应枚举时的处理,可根据需求改为抛出异常
            jsonGenerator.writeNull();
        } catch (NoSuchFieldException | SecurityException e) {
            // 字段反射失败时的处理
            jsonGenerator.writeNull();
        }
    }
}

步骤5:在实体类中使用

在需要转换的Integer字段上同时添加@JsonSerialize和@EnumSerialize注解:

@Data
public class ZkUser {
    private String name;

    @JsonSerialize(using = GenericEnumSerializer.class)
    @EnumSerialize(StatusEnum.class)
    private Integer status;
}

补充说明

后续新增需要转换的枚举类时,只需要让枚举实现CodeEnum接口,然后在实体类字段上添加对应的@EnumSerialize注解即可,无需再编写新的序列化器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 19:35:24