Spring Boot3+OpenJDK17环境下springfox-boot-starter:3.0.0无法工作
问题描述
使用OpenJDK 17 + Spring Boot 3(基于Jakarta EE),引入io.springfox:springfox-boot-starter:3.0.0依赖后,按预期无需额外配置即可使用Swagger UI,但访问以下URL均返回404:
- http://localhost:8080/swagger-ui
- http://localhost:8080/swagger-ui/
- http://localhost:8080/swagger-ui.html
- http://localhost:8080/swagger-ui/index.html
当前build.gradle配置:
plugins { id 'java' id 'org.springframework.boot' version '3.0.0' id 'io.spring.dependency-management' version '1.1.0' id 'org.hibernate.orm' version '6.1.5.Final' } group = 'com.corporation' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' //implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.liquibase:liquibase-core' implementation 'org.hibernate:hibernate-validator:8.0.0.Final' implementation 'org.springdoc:springdoc-openapi-ui:1.6.13' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'org.postgresql:postgresql' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' //testImplementation 'org.springframework.security:spring-security-test' implementation 'org.mapstruct:mapstruct:1.5.3.Final' annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.3.Final' implementation "io.springfox:springfox-boot-starter:3.0.0" } tasks.named('test') { useJUnitPlatform() } hibernate { enhancement { lazyInitialization true dirtyTracking true associationManagement true } }
Controller代码:
@RequiredArgsConstructor @RestController @RequestMapping("/user") @Api("asdfasdf") public class UserController { private final UserService UserService; @GetMapping("/{id}") @ApiOperation("adsfa") public ResponseEntity<UserDto> getUserById(@PathVariable("id") int id) { Optional<User> optionalUser = UserService.findById(id); return optionalUser.map(user -> ResponseEntity.ok(UserMapper.INSTANCE.userToUserDto(user))).orElse(ResponseEntity.status(404).body(null)); } }
问题原因与解决方案
核心原因
- SpringFox 3.0.0不兼容Spring Boot 3:Spring Boot 3全面切换到Jakarta EE API,而SpringFox 3.0.0仍基于旧的Java EE API,底层依赖不兼容导致Swagger组件无法正常初始化。
- 依赖冲突:同时引入
springdoc-openapi-ui和springfox-boot-starter,二者都是OpenAPI/Swagger实现框架,互相干扰导致路由无法正常注册。
解决步骤
- 移除SpringFox依赖:删除build.gradle中的
implementation "io.springfox:springfox-boot-starter:3.0.0",保留springdoc-openapi-ui(它是目前支持Spring Boot 3的主流Swagger实现)。 - 调整Swagger UI访问地址:SpringDoc的默认访问地址为:
http://localhost:8080/swagger-ui/index.html- 简化版:
http://localhost:8080/swagger-ui/
- 替换SpringFox注解(推荐):将Controller中的SpringFox注解替换为SpringDoc对应注解,保持技术栈一致性:
@Api("asdfasdf")→@Tag(name = "asdfasdf")@ApiOperation("adsfa")→@Operation(summary = "adsfa")
对应导入包为io.swagger.v3.oas.annotations.tags.Tag和io.swagger.v3.oas.annotations.Operation。
修改后的build.gradle依赖片段
dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' //implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.liquibase:liquibase-core' implementation 'org.hibernate:hibernate-validator:8.0.0.Final' implementation 'org.springdoc:springdoc-openapi-ui:1.6.13' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'org.postgresql:postgresql' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' //testImplementation 'org.springframework.security:spring-security-test' implementation 'org.mapstruct:mapstruct:1.5.3.Final' annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.3.Final' // 已移除SpringFox依赖 }
修改后的Controller代码示例
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; 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.RestController; import java.util.Optional; @RequiredArgsConstructor @RestController @RequestMapping("/user") @Tag(name = "asdfasdf") public class UserController { private final UserService userService; @GetMapping("/{id}") @Operation(summary = "adsfa") public ResponseEntity<UserDto> getUserById(@PathVariable("id") int id) { Optional<User> optionalUser = userService.findById(id); return optionalUser.map(user -> ResponseEntity.ok(UserMapper.INSTANCE.userToUserDto(user))) .orElse(ResponseEntity.status(404).body(null)); } }
内容的提问来源于stack exchange,提问作者bleschunov
相关产品推荐
相关产品推荐

