Docker容器内TomEE启动成功 反向代理访问返回404故障排查
问题根因
核心冲突为资源类同时使用@WebServlet与JAX-RS@Path("/home")注解,触发TomEE双组件扫描链路冲突:
- TomEE Web容器扫描到
@WebServlet时,会将类标记为原生Servlet注册,直接跳过JAX-RS路径解析逻辑 - TomEE内置的CXF JAX-RS实现扫描到
@Path注解时,会因类已被Servlet注册占用,跳过该REST端点的映射绑定
最终两类组件的路径映射都未生效,所有相关请求直接返回404。
修复步骤
- 移除冲突注解
两类Web组件注解不要叠加在同一个类上:如果要实现JAX-RS接口,直接删除类上的@WebServlet注解;如果要实现原生Servlet,删除所有JAX-RS相关注解即可。
正确的JAX-RS资源类示例:import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/home") public class HomeResource { @GET @Produces(MediaType.APPLICATION_JSON) public String getHomeData() { return "{\"code\":0,\"msg\":\"success\"}"; } } - 补全JAX-RS激活配置
TomEE默认不会自动扫描注册JAX-RS资源,必须在项目中添加JAX-RS应用激活类,否则所有@Path标记的端点都不会对外提供服务:
配置完成后,接口的完整访问路径为import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @ApplicationPath("/api") public class JaxRsActivator extends Application { // 无需重写额外方法,TomEE会自动扫描当前类所在包及子包下的所有JAX-RS资源 }http://IP:8080/example/api/home,注意路径层级不要漏写JAX-RS根路径。 - 逐层排查网络链路
按从内到外的顺序验证连通性,不要直接将问题定位到Nginx层:- 进入TomEE容器内部,执行
curl -v http://127.0.0.1:8080/example/api/home验证容器内服务是否正常返回 - 容器内访问正常后,在宿主机执行curl验证Docker端口映射是否生效,确认启动容器时添加了
-p 8080:8080参数做端口映射 - 宿主机直连正常后,再核对Nginx配置中upstream的IP、端口是否正确,转发路径是否和实际接口路径匹配
- 进入TomEE容器内部,执行
- 核对应用上下文路径
命名为example.war的包部署到TomEE webapps目录时,默认上下文路径为/example,不要随意修改war包名导致上下文路径和预期不符;如果需要自定义上下文路径,可在conf/Catalina/localhost目录下添加对应xml配置文件指定。
注意事项
TomEE启动日志中打印的"应用部署成功"仅代表war包被容器解压加载,不代表内部的Servlet、REST端点都完成了正确的路径映射,不要将"启动无致命报错"作为服务可用的判断依据,必须实际请求接口验证可用性。
内容的提问来源于stack exchange,提问作者King Reload
相关产品推荐
相关产品推荐

