1. 概述
本文将探讨如何在 OpenAPI 中处理日期映射,包括各种日期格式的处理方法。我们将使用两个主流 Maven 插件:swagger-codegen 和 openapi-generator,它们都能根据 OpenAPI 规范生成代码。
2. 示例搭建
首先搭建基础示例,包括初始 YAML 文件和 Maven 插件配置。
2.1 基础 YAML 文件
使用 YAML 文件描述 API(基于 OpenAPI 3.0 规范):
openapi: 3.0.0
info:
title: 日期处理示例 API
version: 0.1.0
paths:
components:
schemas:
Event:
type: object
properties:
organizer:
type: string
2.2 swagger-codegen 插件配置
基础配置如下(最新版本可在 Maven 中央仓库 查找):
<plugin>
<groupId>io.swagger.codegen.v3</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>3.0.52</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/static/event.yaml</inputSpec>
<language>spring</language>
<configOptions>
<java8>true</java8>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
执行生成命令:
mvn clean compile
生成的 Event
类包含构造器、getter/setter 以及重写的 equals()
、hashcode()
和 toString()
方法。
2.3 openapi-generator 插件配置
基础配置如下(最新版本可在 Maven 中央仓库 查找):
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>6.2.1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<skipValidateSpec>true</skipValidateSpec>
<inputSpec>${project.basedir}/src/main/resources/static/event.yaml</inputSpec>
<generatorName>spring</generatorName>
<configOptions>
<java8>true</java8>
<openApiNullable>false</openApiNullable>
<interfaceOnly>true</interfaceOnly>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
⚠️ 关键配置说明:
skipValidateSpec=true
:跳过空paths
验证openApiNullable=false
:避免引入jackson-databing-nullable
依赖interfaceOnly=true
:不生成 Spring Boot 集成测试
执行 mvn compile
同样生成完整的 Event
类。
3. OpenAPI 标准日期映射
OpenAPI 在 string
类型中定义了两种日期格式:date
和 date-time
。
3.1 date 格式
符合 RFC 3339 全日期格式(如 2023-02-08
)。
在 Event
中添加 startDate
属性:
startDate:
type: string
format: date
生成代码:
@JsonProperty("startDate")
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
private LocalDate startDate;
✅ 关键点:
- 默认使用
LocalDate
类 openapi-generator
会添加@DateTimeFormat
注解swagger-codegen
不会添加该注解
3.2 date-time 格式
符合 RFC 3339 日期时间格式(如 2023-02-08T18:04:28Z
)。
在 Event
中添加 endDate
属性:
endDate:
type: string
format: date-time
生成代码:
@JsonProperty("endDate")
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private OffsetDateTime endDate;
✅ 关键点:
- 默认使用
OffsetDateTime
类 - 注解行为与
date
格式一致
4. 使用其他标准日期类
通过配置强制插件使用指定日期类。
4.1 swagger-codegen 配置
<configuration>
<inputSpec>${project.basedir}/src/main/resources/static/event.yaml</inputSpec>
<language>spring</language>
<configOptions>
<java8>true</java8>
<dateLibrary>custom</dateLibrary>
</configOptions>
<typeMappings>
<typeMapping>DateTime=Instant</typeMapping>
<typeMapping>Date=Date</typeMapping>
</typeMappings>
<importMappings>
<importMapping>Instant=java.time.Instant</importMapping>
<importMapping>Date=java.util.Date</importMapping>
</importMappings>
</configuration>
4.2 openapi-generator 配置
<configuration>
<skipValidateSpec>true</skipValidateSpec>
<inputSpec>${project.basedir}/src/main/resources/static/event.yaml</inputSpec>
<generatorName>spring</generatorName>
<configOptions>
<java8>true</java8>
<dateLibrary>custom</dateLibrary>
<openApiNullable>false</openApiNullable>
<interfaceOnly>true</interfaceOnly>
</configOptions>
<typeMappings>
<typeMapping>DateTime=Instant</typeMapping>
<typeMapping>Date=Date</typeMapping>
</typeMappings>
<importMappings>
<importMapping>Instant=java.time.Instant</importMapping>
<importMapping>Date=java.util.Date</importMapping>
</importMappings>
</configuration>
4.3 生成结果
import java.time.Instant;
import java.util.Date;
(...)
@JsonProperty("startDate")
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
private Date startDate;
@JsonProperty("endDate")
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private Instant endDate;
⚠️ 注意事项:
- 插件不会验证类型映射的合理性(比如用
Math
类处理日期也能生成) swagger-codegen
仍不会添加@DateTimeFormat
注解
5. 使用自定义日期模式
当标准日期类无法满足需求时,可用 String
配合正则验证。
在 Event
中添加 ticketSales
属性(格式 DD-MM-YYYY
):
ticketSales:
type: string
description: 票务销售开始日期
example: "01-01-2023"
pattern: "[0-9]{2}-[0-9]{2}-[0-9]{4}"
生成代码(以 openapi-generator
为例):
@JsonProperty("ticketSales")
private String ticketSales;
(...)
/**
* 票务销售开始日期
* @return ticketSales
*/
@Pattern(regexp = "[0-9]{2}-[0-9]{2}-[0-9]{4}")
@Schema(name = "ticketSales", example = "01-01-2023", description = "票务销售开始日期", required = false)
public String getTicketSales() {
return ticketSales;
}
✅ 关键点:
- 需添加
javax.validation
依赖:<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.1.Final</version> </dependency>
- 正则无法区分
DD-MM-YYYY
和MM-DD-YYYY
- 建议添加
description
和example
提高可读性
6. 总结
本文对比了两个主流 OpenAPI 生成器的日期处理能力:
- 内置支持:默认使用
LocalDate
(date
)和OffsetDateTime
(date-time
) - 自定义映射:通过
typeMappings
强制使用其他日期类(如Instant
/Date
) - 兜底方案:使用
String
+ 正则验证处理特殊格式
代码示例可在 GitHub 获取。