OpenAPI Maven Plugin生成错误Java接口名,如何改为ProductApi?
我有一个RestApi接口:HTTP GET /api/v1/products/{productId},该接口以productId作为pathVariable,返回ResponseEntity<ProductInfoDto>对象。我使用OpenApi 6.6.0版本编写了product-openapi.yaml来定义该接口,文件内容如下:
openapi: "3.0.3" info: title: "Online_Store API" version: "1.0.0" servers: - url: "http://localhost:8083" tags: - name: "Product" description: "An API for managing and retrieving product information" paths: /api/v1/products/{productId}: get: tags: - "Product" summary: "Enables to get a product by its id" operationId: "getProductById" parameters: - name: "productId" description: "the identifier of the product which is returned as the return value" in: "path" required: true schema: type: "string" responses: "200": description: "OK" content: '*/*': schema: $ref: "#/components/schemas/ProductInfoDto" components: schemas: ProductInfoDto: type: "object" properties: id: type: "string" format: "uuid" name: type: "string" description: type: "string" price: type: "number" format: "decimal" quantity: type: "integer" format: "int32" ApiResponse: type: "object" properties: data: type: "object" message: type: "string" httpStatusCode: type: "integer" timestamp: type: "string" format: "date-time"
我的项目基于Java 17和Spring Boot 3.1.2开发,实现了ProductsEndpoint作为RestController,代码如下:
package com.zufar.onlinestore.product.endpoint; import com.zufar.onlinestore.openapi.api.ApiApi; import com.zufar.onlinestore.product.api.ProductApi; import com.zufar.onlinestore.product.dto.ProductInfoDto; import com.zufar.onlinestore.product.dto.ProductListWithPaginationInfoDto; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.UUID; @Slf4j @RestController @RequiredArgsConstructor @Validated @RequestMapping(value = ProductsEndpoint.PRODUCTS_URL) public class ProductsEndpoint implements ApiApi { public static final String PRODUCTS_URL = "/api/v1/products"; private final ProductApi productApi; @Override @GetMapping("/{productId}") public ResponseEntity<ProductInfoDto> getProductById(@PathVariable final String productId) { log.info("Received the request to get the product with productId - {}.", productId); ProductInfoDto product = productApi.getProduct(UUID.fromString(productId)); log.info("The product with productId: {} was retrieved successfully", productId); return ResponseEntity.ok() .body(product); } }
我在pom.xml中添加的Apache Maven依赖及插件配置如下:
..... .... ... <properties> <openapi-generator-maven-plugin.version>5.3.0</openapi-generator-maven-plugin.version> <jackson-databind-nullable.version>0.2.1</jackson-databind-nullable.version> <springdoc-openapi-ui.version>1.7.0</springdoc-openapi-ui.version> <validation-api.version>2.0.1.Final</validation-api.version> <javax.annotation-api.version>1.3.2</javax.annotation-api.version> <servlet-api.version>2.5</servlet-api.version> </properties> <dependencies> ..... .... ... <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-ui</artifactId> <version>${springdoc-openapi-ui.version}</version> </dependency> <dependency> <groupId>org.openapitools</groupId> <artifactId>jackson-databind-nullable</artifactId> <version>${jackson-databind-nullable.version}</version> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>${validation-api.version}</version> </dependency> <dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>${javax.annotation-api.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>${servlet-api.version}</version> <scope>provided</scope> </dependency> <build> <plugins> ..... .... ... <plugin> <groupId>org.openapitools</groupId> <artifactId>openapi-generator-maven-plugin</artifactId> <version>${openapi-generator-maven-plugin.version}</version> <executions> <execution> <goals> <goal>generate</goal> </goals> <configuration> <inputSpec>${project.basedir}/src/main/resources/product-openapi.yaml</inputSpec> <generatorName>spring</generatorName> <apiPackage>com.zufar.onlinestore.openapi.api</apiPackage> <modelPackage>com.zufar.onlinestore.product.dto</modelPackage> <supportingFilesToGenerate> ApiUtil.java </supportingFilesToGenerate> <generateModels>false</generateModels> <configOptions> <interfaceOnly>true</interfaceOnly> </configOptions> </configuration> </execution> </executions> </plugin> </plugins> </build>
执行mvn clean package命令构建项目时,OpenApi Maven Plugin生成的是public interface ApApi,而非我预期的public interface ProductApi。请问该如何修复这个问题?
原因分析
生成器默认的命名逻辑出错,加上使用的openapi-generator-maven-plugin版本(5.3.0)较旧,和Spring Boot 3.1.2的Jakarta EE规范兼容性不足,导致生成了错误的接口名称。
修复步骤
1. 升级OpenAPI生成器插件版本
Spring Boot 3.x依赖Jakarta EE,需使用支持该规范的插件版本,将pom.xml中的插件版本改为6.6.0(与你的OpenAPI版本一致):
<openapi-generator-maven-plugin.version>6.6.0</openapi-generator-maven-plugin.version>
2. 在OpenAPI YAML中指定接口名称
在接口的get操作中添加x-codegen-name扩展字段,强制指定生成的接口类名为ProductApi:
paths: /api/v1/products/{productId}: get: tags: - "Product" x-codegen-name: "ProductApi" # 新增此字段 summary: "Enables to get a product by its id" operationId: "getProductById" # 其余配置保持不变
3. 调整插件配置增强兼容性
在插件的configOptions中添加两个关键参数,适配Spring Boot 3并基于tag生成接口名称:
<configOptions> <interfaceOnly>true</interfaceOnly> <useTags>true</useTags> # 基于tag名称生成接口类名 <jakartaEE>true</jakartaEE> # 启用Jakarta EE支持,适配Spring Boot 3 </configOptions>
4. 清理并重新构建
执行命令清理旧生成文件,重新生成接口:
mvn clean generate-sources package
额外优化建议
Spring Boot 3.x已全面切换到Jakarta EE,建议将pom.xml中的javax.*依赖替换为jakarta.*版本,避免兼容性问题:
- 将
javax.validation:validation-api替换为jakarta.validation:jakarta.validation-api:3.0.2 - 将
javax.annotation:javax.annotation-api替换为jakarta.annotation:jakarta.annotation-api:2.1.1 - 将
javax.servlet:servlet-api替换为jakarta.servlet:jakarta.servlet-api:6.0.0
内容的提问来源于stack exchange,提问作者Zufar Sunagatov

