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

Micronaut Introspection枚举字段序列化问题求助

Micronaut中Record DTO的枚举字段序列化问题

我创建了一个用作DTO的record类:

@Introspected()
@Requires(beans=MyEnum.class)//仅为尝试
public record MyDtoRecord(String id, MyEnum enumField) {
}

对应的枚举类代码如下:

@Introspected()
public enum MyEnum {

  AVALUE("aText"),
  BVALUE("bText");

  public String text;

  MyEnum(String text) {
    this.text = text;
  }
}

我期望返回的DTO中,枚举属性能包含其内部字段,例如:

{id:"hello",enumField:{AVALUE:{text:"atext"}}}
//或如下格式:
{id:"hello",enumField:{value:"AVALUE", text:"atext"}}

但实际仅返回枚举标识符:

{id:"hello",enumField:"AVALUE"}

我已尝试在枚举字段上使用自定义注解并配置@Introspected的includedAnnotations参数,也尝试设置accessKind为METHOD,但均无效果。请问是否无法在被@Introspected注解的类中获取枚举字段的内部属性?


解决方案

方法1:配置枚举类的@Introspected参数

默认情况下,Micronaut的@Introspected对枚举仅序列化常量名称,需显式指定要包含的属性及访问方式。修改枚举类:

import io.micronaut.core.annotation.Introspected;
import io.micronaut.core.annotation.AccessKind;

@Introspected(accessKind = {AccessKind.FIELD, AccessKind.METHOD}, includedProperties = {"name", "text"})
public enum MyEnum {

  AVALUE("aText"),
  BVALUE("bText");

  public String text;

  MyEnum(String text) {
    this.text = text;
  }

  public String getName() {
    return this.name();
  }
}

配置后,枚举会被序列化为包含name和text的对象,输出格式类似{"name":"AVALUE","text":"aText"},若要将name改为value,只需把方法名改为getValue()即可。

方法2:自定义Jackson序列化器

若需要完全自定义格式,可编写自定义序列化器:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;

public class MyEnumSerializer extends StdSerializer<MyEnum> {

  protected MyEnumSerializer() {
    super(MyEnum.class);
  }

  @Override
  public void serialize(MyEnum value, JsonGenerator gen, SerializerProvider provider) throws IOException {
    gen.writeStartObject();
    gen.writeStringField("value", value.name());
    gen.writeStringField("text", value.text);
    gen.writeEndObject();
  }
}

然后在枚举类上添加注解指定序列化器:

import com.fasterxml.jackson.databind.annotation.JsonSerialize;

@JsonSerialize(using = MyEnumSerializer.class)
public enum MyEnum {
  // 原有枚举常量及构造代码
}

这种方式可以完全控制枚举的序列化输出结构。

方法3:在Record字段上指定序列化器

如果不想修改枚举类,可直接在Record的枚举字段上添加@JsonSerialize注解:

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.micronaut.core.annotation.Introspected;

@Introspected()
public record MyDtoRecord(String id, @JsonSerialize(using = MyEnumSerializer.class) MyEnum enumField) {
}

关键说明

Micronaut默认对枚举的序列化行为是输出常量名,通过配置@Introspected的includedProperties和accessKind,或自定义Jackson序列化器,均可覆盖默认行为,实现枚举内部字段的序列化。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 16:57:15