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

枚举类上的JsonbTypeDeserializer未触发,如何使其生效?

解决JsonB枚举自定义反序列化器不触发的问题

问题核心原因

你的代码里有两个关键问题:

  1. 注解引用的内部类名称错误:@JsonbTypeSerializer和@JsonbTypeDeserializer中指定的Serializer/Deserializer类不存在,实际内部类名为AddressSerializer和AddressDeserializer,导致JsonB无法加载自定义反序列化器。
  2. JsonB对枚举有默认序列化/反序列化逻辑,默认优先调用枚举的valueOf方法匹配常量名称,若注解配置错误,完全不会触发自定义处理器。

修复步骤

1. 修正注解的内部类引用

将枚举类顶部的注解修改为正确的内部类路径:

@JsonbTypeSerializer(Address.AddressSerializer.class)
@JsonbTypeDeserializer(Address.AddressDeserializer.class)
public enum Address {
    // 原有代码不变
}

2. 优化反序列化器异常处理

避免异常时返回null,改为抛出标准的JsonB异常,便于排查问题:

public static final class AddressDeserializer implements JsonbDeserializer<Address> {
    @Override
    public Address deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) {
        String value;
        try {
            value = parser.getString();
        } catch (IllegalStateException ise) {
            throw new jakarta.json.bind.JsonbException("读取JSON值失败", ise);
        }
        for (Address b : Address.values()) {
            if (b.value().equals(value)) {
                return b;
            }
        }
        throw new jakarta.json.bind.JsonbException("无法识别的地址值: '" + value + "'");
    }
}

3. (可选)显式注册处理器

若注解方式仍不生效,可在创建Jsonb实例时直接注册序列化/反序列化器:

@Test
void addressEnumTest() throws Exception {
    JsonbConfig config = new JsonbConfig()
            .withSerializer(Address.class, new Address.AddressSerializer())
            .withDeserializer(Address.class, new Address.AddressDeserializer());
            
    try (Jsonb jsonb = JsonbBuilder.create(config)) {
        for (Address a : Address.values()) {
            String json = jsonb.toJson(a);
            assertEquals("\"" + a.value() + "\"", json);

            Address result = jsonb.fromJson(json, Address.class);
            assertEquals(a, result);
        }
    }
}

4. 替代方案:使用@JsonbCreator静态方法

如果不想依赖自定义处理器,可添加带@JsonbCreator的静态工厂方法,让JsonB直接通过该方法解析枚举:

public enum Address {
    MAIN_ADDRESS("Main_Address"),
    DELIVERY_ADDRESS("Delivery_Address");

    private String value;

    Address(String value) {
        this.value = value;
    }

    // 原有方法不变

    @JsonbCreator
    public static Address fromValue(String value) {
        for (Address addr : Address.values()) {
            if (addr.value.equals(value)) {
                return addr;
            }
        }
        throw new IllegalArgumentException("无效的地址值: " + value);
    }
}

验证效果

修正后重新运行测试,自定义反序列化器会被正常触发,JSON值"Main_Address"和"Delivery_Address"能正确映射到对应的枚举常量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 20:14:53