我有一个 Spring Boot 项目,使用
springdoc-openapi-starter-webmvc-ui
创建 openapi 规范并显示 Swagger UI。该项目还使用 Jackson 以 JSON 格式序列化数据。 Jackson 配置为理解 java.time
类型并将它们序列化为字符串(请参阅下面的 @Bean ObjectMapper
配置)。然而,当运行项目并查看 Swagger UI 时,openapi 计算的响应模式与真实的序列化不同。请参阅以下两个代码片段中 test2
字段的差异,该字段的类型为 java.time.YearMonth
。另请注意,test1
现场工作的模式计算,其类型为 java.time.Instant
。
实际反应:
{
"test1": "2023-11-06T10:53:42.781130500Z",
"test2": "2023-11"
}
openapi 的响应模式:
{
"test1": "2023-11-06T10:53:42.788Z",
"test2": {
"year": 0,
"month": "JANUARY",
"monthValue": 0,
"leapYear": true
}
}
这是控制器:
@RestController
public class TestController {
@GetMapping("/test")
public TestDto testDto() {
TestDto testDto = new TestDto();
testDto.setTest1(Instant.now());
testDto.setTest2(YearMonth.now());
return testDto;
}
}
这是模型类:
@Data
public class TestDto {
private Instant test1;
private YearMonth test2;
}
以及
ObjectMapper
配置:
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
return objectMapper;
}
我知道我可以做以下事情:
@Data
public class TestDto {
private Instant test1;
@Schema(type = "string", format = "yearmonth", example = "2020-07")
private YearMonth test2;
}
这可行:在 openapi 规范中,架构将如下所示:
{
"test1": "2023-11-06T11:13:56.750Z",
"test2": "2020-07"
}
这正是我想要的。但是,我不想手动添加这个
@Schema
注释,因为这可能会影响多个类中的多个字段。我希望 openapi 规范具有由我的应用程序生成的确切响应模式。我怎样才能实现这个目标?
这是一个 MWE:https://github.com/SebastianOltmanns/springdoc-jackson
可以通过在主类中添加以下代码来实现:
static {
var schema = new Schema<YearMonth>();
schema.format("yearmonth").example(YearMonth.now()).type("string");
SpringDocUtils.getConfig().replaceWithSchema(YearMonth.class, schema);
}
这种方法的缺点是
@Schema
无法用于自定义特定用例,因为它总是被默认用例替换。