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

IBM Liberty 25 OpenAPI:如何拦截枚举注解处理替换.name()为自定义值

解决方案

1. Liberty中注解处理阶段的原生扩展点

IBM Liberty的MicroProfile OpenAPI实现基于Eclipse MicroProfile规范,目前没有直接暴露注解处理阶段的钩子。规范定义的扩展点主要是OASFilter和OASModelReader,其中:

  • OASModelReader用于完全自定义OpenAPI模型生成,但需要从头构建模型,开发成本较高
  • OASFilter仅能在模型生成完成后修改,无法直接访问原始Java类的注解信息

2. 基于OASFilter的优化实现(无需全量类路径扫描)

如果不想使用全量扫描,可以结合CDI和类加载机制,在OASFilter中按需加载枚举类并读取@JsonbProperty注解,步骤如下:

实现步骤

  1. 创建工具类读取枚举常量上的@JsonbProperty值:
public class EnumJsonbPropertyUtils {
    public static Map<String, String> getEnumJsonbMappings(Class<? extends Enum<?>> enumClass) {
        Map<String, String> mappings = new HashMap<>();
        for (Enum<?> constant : enumClass.getEnumConstants()) {
            try {
                JsonbProperty annotation = constant.getClass().getField(constant.name()).getAnnotation(JsonbProperty.class);
                mappings.put(constant.name(), annotation != null ? annotation.value() : constant.name());
            } catch (NoSuchFieldException e) {
                // 处理异常,可按需记录日志
                mappings.put(constant.name(), constant.name());
            }
        }
        return mappings;
    }
}
  1. 实现OASFilter替换枚举Schema值:
@ApplicationScoped
public class EnumJsonbPropertyFilter implements OASFilter {
    @Override
    public Schema filterSchema(Schema schema) {
        // 仅处理字符串类型的枚举Schema
        if (Schema.Type.STRING.equals(schema.getType()) && schema.getEnum() != null && !schema.getEnum().isEmpty()) {
            // 从扩展属性获取枚举类全限定名
            String javaType = (String) schema.getExtensions().get("x-java-type");
            if (javaType != null) {
                try {
                    Class<?> enumClass = Class.forName(javaType);
                    if (enumClass.isEnum()) {
                        Map<String, String> mappings = EnumJsonbPropertyUtils.getEnumJsonbMappings((Class<? extends Enum<?>>) enumClass);
                        List<String> updatedEnums = schema.getEnum().stream()
                                .map(enumName -> mappings.getOrDefault(enumName, enumName))
                                .collect(Collectors.toList());
                        schema.setEnum(updatedEnums);
                    }
                } catch (ClassNotFoundException e) {
                    // 类加载失败时保留原枚举值
                }
            }
        }
        return schema;
    }
}
  1. 在应用类中指定过滤器:
@OpenAPIDefinition(
        filters = EnumJsonbPropertyFilter.class
)
public class MyApplication extends Application {
    // 应用配置逻辑
}

3. 替代方案:使用MicroProfile OpenAPI的@Schema注解

如果允许修改枚举类,可直接使用@Schema注解指定枚举值,生成的Schema会直接使用自定义值:

public enum MyEnum {
    @Schema(allowableValues = {"this-enum-in-kebab-case"})
    THIS_ENUM_IN_KEBAB_CASE,
    @Schema(allowableValues = {"other-enum"})
    OTHER_ENUM,
    SCREAMING_SNAKE_CASE_ENUM;
}

这种方式无需额外扩展,但需要同时维护@JsonbProperty和@Schema两个注解,存在配置重复的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 10:25:20