我在 spring 项目中使用 OpenAPI java 生成器 [1] 和 library:resttemplate, dateLibrary:java8 来根据规范生成客户端。
对于规范中的属性:
targetDate:
type: string
format: date
生成以下代码:
public static final String JSON_PROPERTY_TARGET_DATE = "targetDate";
private LocalDate targetDate;
@javax.annotation.Nonnull
@JsonProperty(JSON_PROPERTY_TARGET_DATE)
@JsonInclude(value = JsonInclude.Include.ALWAYS)
public LocalDate getTargetDate() {
return targetDate;
}
@JsonProperty(JSON_PROPERTY_TARGET_DATE)
@JsonInclude(value = JsonInclude.Include.ALWAYS)
public void setTargetDate(LocalDate targetDate) {
this.targetDate = targetDate;
}
我希望该字段能够序列化为完整日期,例如正如规范所承诺的“2023-01-01”:https://spec.openapis.org/oas/v3.0.0#data-types。然而它实际上被序列化为数组:
[2023,1,1]
。
类似的另一个属性
otherDate:
type: string
format: date-time
被序列化为自纪元以来的秒数,而不是全时。 (我认为这是生成器中的一个错误)
由于代码已生成,我无法添加任何注释。我怎样才能确保日期正确序列化?
[1] openapi-generator-maven-plugin 6.3.0
您的问题与发电机无关,而是与 Jackson 有关。
关于您的 DateTime 格式错误,这是 Jackson 在使用
LocalDate
时序列化 JavaTimeModule
对象的默认方式。 当用户特别要求数组序列化时,这将在这篇文章中讨论。 这可以通过设置您想要的格式来解决,这是在这里回答。
基本要点是这样的。 您需要在字段上方设置
@JsonFormat
注释。你说你不能添加任何注释,但这也是不正确的。 您可以通过在架构中设置 @JsonFormat
扩展,轻松将
x-field-extra-annotation
注释添加到代码中。 例如:
targetDate:
type: string
format: date
x-field-extra-annotation: '@com.fasterxml.jackson.annotation.JsonFormat(shape = com.fasterxml.jackson.annotation.JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")'
这将导致生成以下代码
@com.fasterxml.jackson.annotation.JsonFormat(shape = com.fasterxml.jackson.annotation.JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private LocalDate targetDate;
至于
date-time
被序列化为自纪元以来的秒数,这是杰克逊的一个非常简单的设置。 您可以禁用 SerializationFeature.WRITE_DATES_AS_TIMESTAMPS
。 这将生成 ISO-8601 标准字符串。
由于 openapi-generator 选择不将 LocalDate 的序列化配置为 string(因此破坏了从 yaml string 格式 date 读取的类型),解决方案可能是提供基于配置的 ObjectMapper在提供的设置默认行为的静态函数上
ApiClient apiClient = new ApiClient(
ApiClient.buildWebClientBuilder(
ApiClient.createDefaultObjectMapper(ApiClient.createDefaultDateFormat())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
)
.build());