【问题标题】:Use java.time.Instant to represent DateTime instead of OffsetDateTime使用 java.time.Instant 来表示 DateTime 而不是 OffsetDateTime
【发布时间】:2019-05-21 11:48:00
【问题描述】:

我正在使用openApi maven plugin 为 REST api 生成 java 请求/响应。

请求有一个 DateTime 属性,当我运行生成器时,我得到了表示为 java.time.OffsetDateTime 的属性的 DateTime 属性。问题是我需要将属性表示为 java.time.Instant。

这是请求的 openApi 规范:

"DocumentDto" : {
      "type" : "object",
      "properties" : {
        "uuid" : {
          "type" : "string",
          "format" : "uuid"
        },
        "creationDate" : {
          "type" : "string",
          "format" : "date-time"
        }
      }
    }

生成的java请求:

@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2019-05-21T13:07:21.639+02:00[Europe/Zurich]")
public class DocumentDto {
  public static final String SERIALIZED_NAME_UUID = "uuid";
  @SerializedName(SERIALIZED_NAME_UUID)
  private UUID uuid;


  public static final String SERIALIZED_NAME_TEST = "creationDate";
  @SerializedName(SERIALIZED_NAME_TEST)
  private OffsetDateTime creationDate;
}

maven 插件设置:

<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>3.3.4</version>
    <executions>
        <execution>
            <id>test-service</id>
            <phase>validate</phase>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>
                    ${project.build.directory}/open-api/swagger.json
                </inputSpec>
                <generatorName>java</generatorName>
                <validateSpec>false</validateSpec>
                <generateApis>false</generateApis>
                <groupId>com.test</groupId>
                <artifactId>test-service</artifactId>
                <modelPackage>test.model</modelPackage>
                <apiPackage>test.api</apiPackage>
                <configOptions>
                    <sourceFolder>src/gen/java/main</sourceFolder>
                    <dateLibrary>java8</dateLibrary>
                    <java8>true</java8>
                </configOptions>
            </configuration>
        </execution>              
    </executions>
</plugin>

我已经尝试过如下typeMappingsimportMappings,但它对生成的代码没有影响:

<typeMappings>DateTime=Instant</typeMappings>
<importMappings>Instant=java.time.Instant</importMappings>

【问题讨论】:

    标签: java swagger openapi openapi-generator


    【解决方案1】:

    只需添加到 openapi-generator-maven-plugin 的配置中

    <typeMappings>
         <typeMapping>OffsetDateTime=Instant</typeMapping>
    </typeMappings>
    <importMappings>                                
         <importMapping>java.time.OffsetDateTime=java.time.Instant</importMapping>
    </importMappings>
    

    【讨论】:

      【解决方案2】:

      遇到了同样的问题,但想使用LocalDateTime 而不是Instant。添加以下作品,至少对于 entities

      <configuration>
        <typeMappings>
          <typeMapping>OffsetDateTime=LocalDateTime</typeMapping>
        </typeMappings>
        <importMappings>                
          <importMapping>java.time.OffsetDateTime=java.time.LocalDateTime</importMapping>
        </importMappings>
      </configuration>
      

      即添加了LocalDateTime 的导入,并且yaml 中类型为format: date-time 的任何实体字段都映射到LocalDateTime

      但是,对于 api parameters,没有使用这些设置添加导入。 过了一会儿,我放弃了,而是使用了完全限定的类型,这样就不需要导入了。把上面的typeMapping改成:

      <typeMapping>OffsetDateTime=java.time.LocalDateTime</typeMapping>
      

      之后您生成的方法如下所示:

          default ResponseEntity<List<SomeDto>> someMethodGet(
              @ApiParam(value = "") @Valid @RequestParam(value = "changeDateFrom",
                  required = false) @org.springframework.format.annotation.DateTimeFormat(
                      iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME) java.time.LocalDateTime changeDateFrom,
          {
              return getDelegate().someMethodGet(..., changeDateFrom, ...);
          }
      

      PS1 确保您使用的是最新版本的插件。

      PS2 我使用了委托模式。

      PS2 我用的是弹簧模型。

      【讨论】:

        【解决方案3】:

        您的更改会被生成器的dateLibrary 配置覆盖。 要覆盖 datedate-time 格式类型,您最好通过指定 Java 生成器无法识别的值来禁用 dateLibrary

        将此添加到您插件的&lt;configuration&gt; 以实现此目的:

          <configOptions>
            <java8>true</java8>
            <dateLibrary>custom</dateLibrary>
          </configOptions>
          <typeMappings>
            <typeMapping>DateTime=Instant</typeMapping>
            <typeMapping>Date=LocalDate</typeMapping>
          </typeMappings>
          <importMappings>
            <importMapping>Instant=java.time.Instant</importMapping>
            <importMapping>LocalDate=java.time.LocalDate</importMapping>
          </importMappings>
        

        您可能还想添加 &lt;jsr310&gt;true&lt;/jsr310&gt; 配置选项,因为当 dateLibrary 为 java8 时它会自动启用(但据我所知,这主要用于生成客户端)。

        【讨论】:

          【解决方案4】:

          您确实必须像@MaksimYakidovich 所说的那样添加映射,但也要更改您的规范 "format" : "offset-date-time" 而不是 date-time

          【讨论】:

            【解决方案5】:

            我知道问题是关于 openapi-generator-maven-plugin,但由于寻找 org.openapi.generator 的相同配置 gradle 插件将我带到这里,我想这可能对其他人有用:

            org.openapi.generator gradle 插件的等价物是:

            openApiGenerate {
                // ...
                typeMappings = [
                    OffsetDateTime: "Instant"
                ]
                importMappings = [
                    "java.time.OffsetDateTime": "java.time.Instant"
                ]
            }
            

            【讨论】:

            • 导入未更改的问题。有什么想法吗?
            猜你喜欢
            • 1970-01-01
            • 2020-01-06
            • 2020-04-13
            • 2022-01-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-09
            相关资源
            最近更新 更多