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

SpringDoc-OpenAPI运行时动态生成枚举的实现方案问询

解决SpringDoc中动态设置字段允许值的问题

spring-doc提供了SchemaCustomizer扩展接口,完全可以满足你动态设置字段允许值的需求,而且能批量处理数百个类,不用硬编码@Schema注解。以下是具体实现步骤:

1. 实现SchemaCustomizer接口自定义Schema逻辑

这个接口是spring-doc的核心扩展点,允许你在生成OpenAPI Schema的过程中,动态修改字段的属性。你可以在服务器启动时一次性计算好允许值,然后批量应用到目标字段上。

示例代码:

首先定义一个负责计算允许值的组件(启动时初始化一次):

@Component
public class SizeValueProvider {
    private List<String> allowedSizes;

    @PostConstruct
    public void init() {
        // 这里写运行时计算允许值的逻辑,比如从配置、数据库读取,启动时执行一次
        allowedSizes = Arrays.asList("SMALL", "MEDIUM", "LARGE", "XLARGE");
    }

    public List<String> getAllowedSizes() {
        return allowedSizes;
    }
}

然后实现SchemaCustomizer,批量处理目标类的字段:

@Component
public class DynamicAllowableValuesCustomizer implements SchemaCustomizer {

    private final List<String> allowedSizes;

    // 注入预计算好允许值的组件
    public DynamicAllowableValuesCustomizer(SizeValueProvider sizeValueProvider) {
        this.allowedSizes = sizeValueProvider.getAllowedSizes();
    }

    @Override
    public void customize(SchemaContext context) {
        Schema schema = context.getSchema();
        Class<?> targetClass = context.getType();

        // 方式1:直接指定单个类(比如RelativeSize)
        if (RelativeSize.class.equals(targetClass)) {
            Property sizeProperty = schema.getProperties().get("size");
            if (sizeProperty != null) {
                sizeProperty.setAllowableValues(new AllowableListValues(allowedSizes, String.class));
            }
        }

        // 方式2:用自定义注解批量处理数百个类
        if (targetClass.isAnnotationPresent(DynamicAllowableField.class)) {
            DynamicAllowableField annotation = targetClass.getAnnotation(DynamicAllowableField.class);
            String fieldName = annotation.value();
            Property targetProperty = schema.getProperties().get(fieldName);
            if (targetProperty != null) {
                targetProperty.setAllowableValues(new AllowableListValues(allowedSizes, String.class));
            }
        }
    }
}

自定义批量处理的注解:

为了方便标记需要处理的类,定义一个注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DynamicAllowableField {
    // 指定需要设置允许值的字段名,默认是size
    String value() default "size";
}

之后只要在需要处理的类上加上@DynamicAllowableField(或指定字段名@DynamicAllowableField("customSize")),就能自动应用动态允许值。

2. 验证效果

启动应用后,访问你的OpenAPI文档页面(比如/swagger-ui.html),查看目标字段的Schema定义,会发现allowableValues已经被设置为你动态计算的列表。生成API客户端时,该字段会被识别为枚举类型,和硬编码@Schema的效果完全一致。

注意事项

  • 确保允许值的计算逻辑只在启动时执行一次,避免重复计算影响性能。
  • 如果字段类型不是String,要对应调整AllowableListValues的第二个类型参数(比如Integer.class)。
  • 如果需要区分不同类的允许值,可以在自定义注解中添加参数,或者在SchemaCustomizer中根据类的不同加载对应允许值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 11:27:20