IBM Liberty 25 OpenAPI:如何拦截枚举注解处理替换.name()为自定义值
解决方案
1. Liberty中注解处理阶段的原生扩展点
IBM Liberty的MicroProfile OpenAPI实现基于Eclipse MicroProfile规范,目前没有直接暴露注解处理阶段的钩子。规范定义的扩展点主要是OASFilter和OASModelReader,其中:
OASModelReader用于完全自定义OpenAPI模型生成,但需要从头构建模型,开发成本较高OASFilter仅能在模型生成完成后修改,无法直接访问原始Java类的注解信息
2. 基于OASFilter的优化实现(无需全量类路径扫描)
如果不想使用全量扫描,可以结合CDI和类加载机制,在OASFilter中按需加载枚举类并读取@JsonbProperty注解,步骤如下:
实现步骤
- 创建工具类读取枚举常量上的
@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; } }
- 实现
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; } }
- 在应用类中指定过滤器:
@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
相关产品推荐
相关产品推荐

