Spring OpenAPI Codegen生成委托后API未暴露及Swagger UI无法访问排查
核心问题分析
从你的配置和代码来看,问题集中在路由映射缺失、Spring Boot 3版本兼容性以及组件扫描范围三个方面:
1. 委托模式下缺少路由控制器
开启delegatePattern=true时,OpenAPI Generator仅生成EmployeesDataApi(路由接口)和EmployeesDataApiDelegate(业务委托接口),不会自动实现带@RequestMapping的路由控制器类。你的代码只实现了委托接口,但没有对应的路由类处理请求映射,导致所有API请求返回404。
2. 依赖版本不兼容(Spring Boot 3)
你使用Spring Boot 3.0.2,但搭配的springdoc-openapi-ui:1.6.15是适配Spring Boot 2.x的版本,完全不兼容Spring Boot 3;同时依赖中的javax.*包在Spring Boot 3中已全面替换为jakarta.*,旧包会导致组件加载失败、Swagger UI无法启动。
3. 组件扫描范围未覆盖生成的API类
你的主应用类默认扫描com.jainva.api及其子包,但生成的API类在com.openapi.gen.springboot.api下,Spring无法加载该包下的路由控制器,进一步加剧了404问题。
4. 控制器注解冲突
EmployeesController同时标注@RestController和@Service,导致Spring对类的定位混乱——委托实现类只需@Service即可,路由映射由生成的API控制器负责。
解决方案
1. 修复依赖兼容性
更新pom.xml中的依赖,适配Spring Boot 3:
<!-- 替换为Spring Boot 3兼容的springdoc UI依赖 --> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.2.0</version> </dependency> <!-- 替换所有javax.*依赖为jakarta.* --> <dependency> <groupId>jakarta.annotation</groupId> <artifactId>jakarta.annotation-api</artifactId> <version>2.1.1</version> </dependency> <dependency> <groupId>jakarta.validation</groupId> <artifactId>jakarta.validation-api</artifactId> <version>3.0.2</version> </dependency> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency> <!-- 移除旧的swagger-annotations,springdoc已自带兼容版本 --> <!-- <dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-annotations</artifactId> <version>2.2.8</version> </dependency> -->
2. 扩大Spring组件扫描范围
在主应用类上添加@ComponentScan,包含生成的API包:
@SpringBootApplication @ComponentScan(basePackages = {"com.jainva.api", "com.openapi.gen.springboot.api"}) public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
3. 修正控制器注解
移除@RestController,仅保留@Service作为委托实现类:
@Service public class EmployeesController implements EmployeesDataApiDelegate { private final EmployeServices empServices; public EmployeesController(EmployeServices empServices) { this.empServices = empServices; } // 移除手动添加的@PostMapping,路由由生成的API控制器负责 // 仅保留委托接口的实现方法 @Override public ResponseEntity<EmployeesData> getAllEmployeesData() { System.out.println("Controller layer for get all employees"); try { EmployeesData ed = new EmployeesData(); ed.setEmployees(empServices.getAllEmployees()); return ResponseEntity.ok().body(ed); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); } } }
4. 验证OpenAPI Generator配置
确保插件生成了完整的路由控制器类,可移除supportingFilesToGenerate配置,让插件生成所有必要文件:
<configuration> <inputSpec>${project.basedir}/src/main/resources/api.yaml</inputSpec> <generatorName>spring</generatorName> <apiPackage>com.openapi.gen.springboot.api</apiPackage> <modelPackage>com.openapi.gen.springboot.dto</modelPackage> <configOptions> <delegatePattern>true</delegatePattern> <serializableModel>true</serializableModel> <sourceFolder>src/gen/java/main</sourceFolder> <useTags>true</useTags> </configOptions> </configuration>
5. 调整Swagger UI访问配置
在application.properties中添加:
springdoc.swagger-ui.path=/swagger-ui.html
之后通过http://localhost:8956/swagger-ui.html访问Swagger UI。
内容的提问来源于stack exchange,提问作者VAIBHAV JAIN

