用于 Java 生成不一致类的 OpenAPI Maven 插件

如何解决用于 Java 生成不一致类的 OpenAPI Maven 插件

我们使用 openapi-generator-maven-plugin 版本 5.0.1 来生成我们的 API。我正在尝试指定一个包含 DTO 和文件的请求。

一个奇怪的是,生成代码没有使用 DTO,它基本上将字段扁平化,因此 API 期望指定每个字段。然而,我们并不太关心这个问题,因为我们可以只指定每个字段(尽管如果它按预期工作会很好)。

正在扼杀我们的问题是为 API 和 API Delegate 生成的类彼此不一致。生成的 API 将每个字段视为 String。但是,API 委托将它们视为 Optional<String>。因此,当我们尝试编译代码时,API 会收到编译错误,因为它正在将 String 传递给 Delegate,而 Delegate 需要 Optional<String>

这是我们的 POM,以及相关的依赖项和插件配置:

        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.openapitools</groupId>
            <artifactId>jackson-databind-nullable</artifactId>
            <version>0.2.1</version>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
...
<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>5.0.1</version>
    <executions>
        <execution>
            <id>processor-Generate</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>
                    ${project.basedir}/apis/innovation-ivp-inventory-accuracy-acl-api.yml
                </inputSpec>
                <generatorName>spring</generatorName>
                <apiPackage>${project.groupId}.inventory.accuracy.acl.api</apiPackage>
                <modelPackage>${project.groupId}.inventory.accuracy.acl.dto</modelPackage>
                <invokerPackage>${project.groupId}.inventory.accuracy.acl.api.handler</invokerPackage>
                <supportingFilesToGenerate>ApiUtil.java,OpenAPIDocumentationConfig.java
                </supportingFilesToGenerate>
                <configOptions>
                    <useTags>true</useTags>
                    <dateLibrary>java8-localdatetime</dateLibrary>
                    <java8>true</java8>
                    <delegatePattern>true</delegatePattern>
                    <useBeanValidation>true</useBeanValidation>
                    <uSEOptional>true</uSEOptional>
                    <configPackage>${project.groupId}.inventory.accuracy.acl.api</configPackage>
                </configOptions>
                <output>${project.build.directory}/generated-sources</output>
            </configuration>
        </execution>
    </executions>
</plugin>

这是我们的 OpenAPI 规范:

'/email':
  post:
    tags:
      - email-service
    summary: Email Service
    operationId: sendEmail
    requestBody:
      required: true
      content:
        multipart/mixed:
          schema:
            allOf:
              - $ref: '#/components/schemas/EmailRequestDTO'
              - type: object
                properties:
                  file:
                    type: string
                    format: binary
    responses:
      "200":
        description: OK
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmailResponseDTO'
components:
  schemas:
    EmailRequestDTO:
      type: object
      properties:
        sendTo:
          type: string
        sentFrom:
          type: string
        subject:
          type: string
        content:
          type: string
    EmailResponseDTO:
      type: object
      properties:
        status:
          type: string
        errorMessage:
          type: string

这里是OpenAPI生成的API类(注意参数都是String):

public interface EmailServiceApi {

    @ApiOperation(value = "Email Service",nickname = "sendEmail",notes = "",response = EmailResponseDTO.class,tags={ "email-service",})
    @ApiResponses(value = {
        @ApiResponse(code = 200,message = "OK",response = EmailResponseDTO.class) })
    @PostMapping(
        value = "/email",produces = { "application/json" },consumes = { "multipart/mixed" }
    )
    default ResponseEntity<EmailResponseDTO> sendEmail(@ApiParam(value = "") @Valid @RequestPart(value = "sendTo",required = false)  String sendTo,@ApiParam(value = "") @Valid @RequestPart(value = "sentFrom",required = false)  String sentFrom,@ApiParam(value = "") @Valid @RequestPart(value = "subject",required = false)  String subject,@ApiParam(value = "") @Valid @RequestPart(value = "content",required = false)  String content,@ApiParam(value = "") @Valid @RequestPart(value = "file",required = false) multipartfile file) {
        return getDelegate().sendEmail(sendTo,sentFrom,subject,content,file);
    }
}

这里是OpenAPI生成的API Delegate类(注意参数都是Optional):

public interface EmailServiceApiDelegate {
    default ResponseEntity<EmailResponseDTO> sendEmail(Optional<String> sendTo,Optional<String> sentFrom,Optional<String> subject,Optional<String> content,multipartfile file) {
        getRequest().ifPresent(request -> {
            for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {
                if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
                    String exampleString = "{ \"errorMessage\" : \"errorMessage\",\"status\" : \"status\" }";
                    ApiUtil.setExampleResponse(request,"application/json",exampleString);
                    break;
                }
            }
        });
        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
    }
}

解决方法

使用 allOf 将列出的所有架构合二为一。 EmailRequestDTO 的属性和内联定义的对象的属性作为参数而不是 DTO 生成。见https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/#allof

如果您不想在委托中生成可选字符串作为参数,请删除 useOptional 配置。见https://openapi-generator.tech/docs/generators/spring/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?