Jetty部署GAE项目:@Path注解类404及Java11适配问题
解决方案
一、WEB-INF/classes下REST接口404问题排查
- 确认Jersey资源包注册正确:检查
ResourceConfig子类(或web.xml中的jersey.config.server.provider.packages参数)是否指向REST接口所在的包路径,确保注解类能被Jersey扫描到。 - 验证GAE Jetty部署配置:确认war包被正确挂载到Jetty的webapp目录,Jetty启动配置中没有额外拦截REST请求的规则。
- 检查编译与注解有效性:确保带
@Path注解的类和方法已正确编译到WEB-INF/classes目录,Jersey 2.25支持该注解的自动扫描,排除编译遗漏问题。
二、无需修改源码解决Jersey与DefaultServlet路径冲突
方案1:通过Jersey配置转发静态资源
修改web.xml(或Jetty启动时的Servlet配置),将Jersey映射到/*,同时配置静态资源转发规则:
<servlet> <servlet-name>JerseyServlet</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>你的REST接口包路径</param-value> </init-param> <init-param> <param-name>jersey.config.servlet.filter.staticContentRegex</param-name> <param-value>/.*\.(html|css|js|png|jpg|gif)$</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>JerseyServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <servlet> <servlet-name>default</servlet-name> <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class> </servlet>
该配置让Jersey拦截所有请求,匹配到静态资源后缀时自动转发给DefaultServlet处理,REST请求由Jersey自行处理,无需修改接口的@Path前缀。
方案2:Jetty自定义Handler实现请求分流
在clinixwip11Jtty项目中添加自定义HandlerWrapper,根据请求路径分流:
public class PathRoutingHandler extends HandlerWrapper { private static final Pattern STATIC_RESOURCE_PATTERN = Pattern.compile("/.*\\.(html|css|js|png|jpg|gif)$"); @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { if (STATIC_RESOURCE_PATTERN.matcher(target).matches()) { getHandler().handle(target, baseRequest, request, response); } else { ServletHolder jerseyHolder = getServer().getServletContext().getServletHolder("JerseyServlet"); jerseyHolder.getServlet().service(request, response); } } }
然后在Jetty启动代码中注册该Handler:
Server server = new Server(); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); context.setResourceBase("war包所在路径"); // 注册Jersey Servlet ServletHolder jerseyHolder = new ServletHolder("JerseyServlet", ServletContainer.class); jerseyHolder.setInitParameter("jersey.config.server.provider.packages", "你的REST接口包路径"); context.addServlet(jerseyHolder, "/"); // 注册DefaultServlet ServletHolder defaultHolder = new ServletHolder("default", DefaultServlet.class); context.addServlet(defaultHolder, "/*"); // 添加路由Handler PathRoutingHandler routingHandler = new PathRoutingHandler(); routingHandler.setHandler(context); server.setHandler(routingHandler); server.start();
通过Jetty Handler层实现请求分流,无需修改war包内的任何代码或配置。
方案3:配置Jersey ApplicationPath等效参数
如果war包中没有自定义Application子类,可在web.xml中添加如下配置:
<servlet> <servlet-name>JerseyServlet</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>org.glassfish.jersey.server.ResourceConfig</param-value> </init-param> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>你的REST接口包路径</param-value> </init-param> <init-param> <param-name>jersey.config.server.application.path</param-name> <param-value>/</param-value> </init-param> <init-param> <param-name>jersey.config.servlet.filter.staticContentRegex</param-name> <param-value>/.*\.(html|css|js|png|jpg|gif)$</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>JerseyServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
此配置将Jersey的根路径设为/,同时自动转发静态资源请求,无需调整接口的@Path注解。
内容的提问来源于stack exchange,提问作者Applix Systems
相关产品推荐
相关产品推荐

