如何在SpringDoc中修改LocalDateTime的默认Swagger Schema并解决字段自定义描述丢失问题?
我之前也碰到过一模一样的问题!当用SpringDocUtils.getConfig().replaceWithSchema()全局替换LocalDateTime的Schema时,确实会覆盖字段上@Schema注解的自定义描述、示例这些属性——因为这个全局替换是直接替换了该类型的整个Schema定义,字段上的局部配置会被直接忽略。
下面给你两种可行的解决方案:
方案1:自定义ModelConverter(推荐)
这种方式既能给LocalDateTime设置全局默认的格式和示例,又能完整保留字段上@Schema注解的局部配置(比如描述、自定义示例)。
步骤1:创建自定义ModelConverter类
这个类会在SpringDoc生成Schema的流程中,对LocalDateTime类型做特殊处理,同时合并字段的局部注解配置:
import io.swagger.v3.core.converter.ModelConverter; import io.swagger.v3.core.converter.ModelConverterContext; import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.StringSchema; import org.springdoc.core.converters.ModelConverterUtils; import java.lang.reflect.Type; import java.time.LocalDateTime; import java.util.Iterator; public class LocalDateTimeModelConverter implements ModelConverter { @Override public Schema<?> resolve(Type type, ModelConverterContext context, Iterator<ModelConverter> chain) { // 先让默认的转换器处理,拿到基础的Schema(包含字段@Schema的配置) Schema<?> schema = chain.next().resolve(type, context, chain); if (type instanceof Class<?> && LocalDateTime.class.isAssignableFrom((Class<?>) type)) { StringSchema stringSchema = new StringSchema(); // 设置全局默认的示例和正则规则 stringSchema.example("2021-07-05T10:35:17.000"); stringSchema.pattern("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}[.]\\d{3}"); // 合并字段@Schema注解中的配置(比如描述、自定义示例) if (schema != null) { stringSchema.description(schema.getDescription()); if (schema.getExample() != null) { stringSchema.example(schema.getExample()); } // 可根据需求添加其他需要保留的属性,比如required、nullable等 } return stringSchema; } return schema; } }
步骤2:注册自定义Converter到SpringDoc
在配置类中把上面的Converter加入SpringDoc的处理链:
import org.springdoc.core.SpringDocUtils; import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; @Configuration public class SpringDocCustomConfig { @PostConstruct public void configureLocalDateTimeSchema() { SpringDocUtils.getConfig().addModelConverter(new LocalDateTimeModelConverter()); } }
这样处理后,全局的LocalDateTime都会使用你设置的默认格式和示例,同时字段上的@Schema(description = "important date")会被完整保留,甚至如果字段设置了自定义示例,还会覆盖全局默认值。
方案2:字段级显式指定Schema(临时 workaround)
如果你不想写自定义Converter,也可以在字段的@Schema注解中显式指定完整的Schema配置,同时保留描述:
@Schema( description = "important date", schema = @Schema( type = "string", example = "2021-07-05T10:35:17.000", pattern = "\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}[.]\\d{3}" ) ) private LocalDateTime aDate;
不过这种方式会重复代码,不符合你一开始想避免重复注解的需求,只适合个别字段的特殊场景。
为什么原方式会丢失描述?
当调用replaceWithSchema()时,SpringDoc会直接用你传入的Schema完全替换LocalDateTime对应的默认Schema。处理字段时,它会优先使用全局替换的Schema,而忽略字段上@Schema注解中的描述、示例等属性——除非这些属性在全局Schema中没有设置,但你这里已经设置了example和pattern,所以局部配置被完全覆盖了。
内容的提问来源于stack exchange,提问作者AndrzejPw

