迁移至Jakarta后JAX-RS资源返回HTTP/1.1 404 Not Found问题
问题概述
将基于javax的EE应用升级到Jakarta EE 10.x版本后,原有的JAX-RS资源无法访问,执行curl请求返回404错误。
依赖配置
implementation("com.google.code.gson:gson:2.11.0")
JAX-RS控制器代码
import com.bewherewhen.ejb.UsersJSONEJB; import jakarta.inject.Inject; import jakarta.inject.Named; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Named @Path("/") public class UsersJSONController { private static final Logger LOGGER = LoggerFactory.getLogger(UsersJSONController.class); @Inject private UsersJSONEJB usersJSONEJB; @GET @Produces(MediaType.APPLICATION_JSON) @Path("/get-all-users") public Response getAllUsersJSON() { LOGGER.info(">>>>>>> UsersJSONController getAllUsersJSON ....."); String json = usersJSONEJB.getAllUsersJSON(); LOGGER.info(">>>>>>> 1.6 UsersJSONEJB getAllUsersJSON = {}", json); return Response.ok(json, MediaType.APPLICATION_JSON).build(); } }
(注:原代码补充了缺失的LOGGER和usersJSONEJB声明)
请求报错信息
curl -v http://127.0.0.1:8080/get-all-users/ * Trying 127.0.0.1:8080... * Connected to 127.0.0.1 (127.0.0.1) port 8080 > GET /get-all-users/ HTTP/1.1 > Host: 127.0.0.1:8080 > User-Agent: curl/8.7.1 > Accept: */* > * Request completely sent off < HTTP/1.1 404 Not Found < Connection: keep-alive < Content-Length: 74 < Content-Type: text/html < Date: Sun, 04 Aug 2024 17:07:07 GMT < * Connection #0 to host 127.0.0.1 left intact <html><head><title>Error</title></head><body>404 - Not Found</body></html>
环境信息
- macOS Sonoma 14.6
- gson 2.11.0
- curl 8.9.1
- WildFly Distribution - 33.0.0.Final
- Jakarta EE 10.0.0 & 11.0.0-M4
- JDK 21.0.2
- Kotlin 2.0.0
- Mojarra 4.1.0
排查与解决步骤
1. 检查应用上下文路径
WildFly默认将war包名称(去掉.war后缀)作为应用上下文路径。如果你的war包名为your-app.war,正确请求路径应为http://127.0.0.1:8080/your-app/get-all-users,而非直接访问根路径。
2. 添加JAX-RS Application类
Jakarta EE 10中JAX-RS资源需要明确激活,创建继承jakarta.ws.rs.core.Application的类并添加@ApplicationPath注解:
import jakarta.ws.rs.ApplicationPath; import jakarta.ws.rs.core.Application; @ApplicationPath("/api") public class JaxRsApplication extends Application { }
此时控制器完整路径变为/api/get-all-users,请求地址应为http://127.0.0.1:8080/your-app/api/get-all-users。
3. 移除不必要的@Named注解
JAX-RS资源由JAX-RS容器管理,无需CDI的@Named注解,该注解可能引发容器扫描冲突,直接移除即可。
4. 验证依赖的Jakarta版本兼容性
确保所有JAX-RS相关依赖均为Jakarta版本,无残留的javax.ws.rs依赖。WildFly 33自带Jakarta EE 10的JAX-RS实现,无需显式引入jakarta.ws.rs-api,可通过依赖树检查冲突:
# Gradle用户执行 ./gradlew dependencies
5. 检查WildFly启动日志
查看standalone/log/server.log,搜索JAX-RS相关日志:
- 确认是否有
Registered RESTful resource classes信息,验证资源是否被加载; - 排查是否存在类加载错误、CDI注入失败等异常(比如
UsersJSONEJB无法注入的问题)。
6. 调整请求路径的斜杠
控制器类上@Path("/") + 方法上@Path("/get-all-users"),实际匹配路径为/get-all-users(无末尾斜杠)。去掉curl请求末尾斜杠重试:
curl -v http://127.0.0.1:8080/your-app/get-all-users
内容的提问来源于stack exchange,提问作者NOTiFY

