为RESTeasy Java应用集成Swagger遇404错误求助
问题描述
按照Swagger官方文档配置后,无法访问Swagger端点,始终返回404错误。
技术栈
- Tomcat 10.0.1
- Java 17
目标
通过http://localhost:8080/sample/openapi访问美观的API文档
已配置内容
1. src/main/resources/openapi.yaml
openapi: "3.0.3" info: title: "My API2" version: "1.0" servers: - url: "http://localhost:8080/" paths:
2. TimeToolRestApplication.java
@ApplicationPath("/api") public class TimeToolRestApplication extends Application { private Set<Object> singletons = new HashSet<>(); private static final Logger logger = LogManager.getLogger(TimeToolRestApplication.class); public TimeToolRestApplication() { singletons.add(new HealthController()); } @Override public Set<Object> getSingletons() { return singletons; } }
3. HealthController.java
@Path("/v1") public class HealthController { @GET @Path("/health") public Response healthcheck() { return Response.ok().entity(true).build(); } }
4. pom.xml依赖配置
<properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <resteasy.version>6.2.4.Final</resteasy.version> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.3.2</version> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-yaml</artifactId> <version>2.15.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-servlet-initializer</artifactId> <version>${resteasy.version}</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-core</artifactId> <version>${resteasy.version}</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-client</artifactId> <version>${resteasy.version}</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jaxb-provider</artifactId> <version>${resteasy.version}</version> </dependency> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-jaxrs2</artifactId> <version>2.2.14</version> </dependency> <dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-jaxrs2-servlet-initializer-v2</artifactId> <version>2.2.14</version> </dependency> <dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-core-jakarta</artifactId> <version>2.2.14</version> </dependency> </dependencies>
已尝试的方法
按照Swagger官方快速入门文档中的方法配置,无论是否使用初始化器,问题均未解决。
解决方案
1. 修正Swagger依赖适配Jakarta EE
Tomcat 10+采用Jakarta EE规范,当前依赖混合了Jakarta与非Jakarta版本的Swagger包,会导致兼容性冲突。需替换所有Swagger依赖为Jakarta专属版本:
将pom.xml中的Swagger依赖替换为:
<dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-jaxrs2-jakarta</artifactId> <version>2.2.14</version> </dependency> <dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-core-jakarta</artifactId> <version>2.2.14</version> </dependency> <dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-jaxrs2-servlet-initializer-jakarta</artifactId> <version>2.2.14</version> </dependency>
同时移除原有的swagger-jaxrs2和swagger-jaxrs2-servlet-initializer-v2依赖。
2. 手动注册Swagger资源
由于自定义了Application子类(TimeToolRestApplication),Swagger的自动初始化机制可能失效,需手动注册核心资源类:
修改TimeToolRestApplication.java,添加Swagger资源到单例集合:
@ApplicationPath("/api") public class TimeToolRestApplication extends Application { private Set<Object> singletons = new HashSet<>(); private static final Logger logger = LogManager.getLogger(TimeToolRestApplication.class); public TimeToolRestApplication() { singletons.add(new HealthController()); // 注册Swagger核心资源 singletons.add(new OpenApiResource()); singletons.add(new SwaggerUiResource()); } @Override public Set<Object> getSingletons() { return singletons; } }
3. 配置目标访问路径
默认情况下,Swagger的OpenAPI端点为/openapi.json或/openapi.yaml,结合你的应用上下文sample和应用路径/api,初始可用地址为:http://localhost:8080/sample/api/openapi.yaml
若要通过/sample/openapi访问,可通过以下两种方式配置:
方式A:添加Swagger UI Servlet到web.xml
若项目无web.xml,创建src/main/webapp/WEB-INF/web.xml并添加:
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd" version="6.0"> <servlet> <servlet-name>SwaggerUI</servlet-name> <servlet-class>io.swagger.v3.jaxrs2.integration.SwaggerUiServlet</servlet-class> <init-param> <param-name>openApiSpec</param-name> <param-value>/api/openapi.yaml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>SwaggerUI</servlet-name> <url-pattern>/openapi/*</url-pattern> </servlet-mapping> </web-app>
配置完成后访问http://localhost:8080/sample/openapi即可查看Swagger UI界面。
方式B:使用Swagger配置类自定义路径
创建Swagger配置类:
@OpenAPIDefinition(info = @Info(title = "My API2", version = "1.0")) @ApplicationPath("/api") public class SwaggerConfig extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<>(); // 注册API控制器 classes.add(HealthController.class); // 注册Swagger资源 classes.add(OpenApiResource.class); classes.add(SwaggerUiResource.class); return classes; } }
然后在src/main/resources/swagger-config.yaml中配置端点路径:
openapi: path: /openapi
4. 补充API注解生成完整文档
为控制器方法添加Swagger注解,确保生成的API文档包含接口信息:
修改HealthController.java:
@Path("/v1") @Tag(name = "健康检查", description = "系统健康状态接口") public class HealthController { @GET @Path("/health") @Operation(summary = "健康检查", description = "返回系统是否正常运行") @ApiResponse(responseCode = "200", description = "系统正常") public Response healthcheck() { return Response.ok().entity(true).build(); } }
5. 清理部署
执行mvn clean install清理编译缓存,重启Tomcat服务器确保新配置生效。
内容的提问来源于stack exchange,提问作者Involute

