openapi java 生成器将 LocalDate 序列化为数组而不是完整日期

问题描述 投票:0回答:2

我在 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

java openapi jackson-databind openapi-generator openapi-generator-maven-plugin
2个回答
7
投票

您的问题与发电机无关,而是与 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 标准字符串。


0
投票

由于 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());
© www.soinside.com 2019 - 2024. All rights reserved.