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
相关产品推荐
相关产品推荐

