Jersey多Servlet容器配置问题:URL映射冲突与404错误解决
问题根源
改成具体路径后出现404的核心原因是Jersey ServletContainer的路径匹配逻辑:
当你把Servlet映射到/rt/ni/verificar这类具体路径时,Jersey会将该路径视为自身的上下文根路径。而你的资源类EnWS里的@Path注解大概率是@Path("/verificar"),此时请求/rt/ni/verificar?request=...到达Jersey后,剩余的路径是空字符串,无法匹配到@Path("/verificar")的资源方法,因此返回404。
解决方案
下面提供两种可行思路,优先推荐第一种,既能满足客户端URL要求,又避免Servlet冲突:
方案一:统一用一个Jersey Servlet处理所有/rt/ni/*请求
将两个服务类注册到同一个ServletContainer中,既符合客户端对URL模式的要求,又不会出现Tomcat映射冲突。
修改后的web.xml配置:
<servlet> <servlet-name>NiService</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.classnames</param-name> <param-value> org.glassfish.jersey.media.multipart.MultiPartFeature; es.ti.ws.ni.services.EnWS; es.ti.ws.ni.exp.services.Enexp </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>NiService</servlet-name> <url-pattern>/rt/ni/*</url-pattern> </servlet-mapping>
配置完成后,Jersey会根据两个资源类上的@Path注解自动区分请求:
- 请求
/rt/ni/verificar?request=...会匹配EnWS类中@Path("/verificar")的方法 - 请求
/rt/ni/obtener?request=...会匹配Enexp类中@Path("/obtener")的方法
方案二:保留两个Servlet,调整映射路径与资源类注解
如果必须分开两个Servlet,需调整Servlet映射路径为带通配符的形式,同时修改资源类的@Path注解:
1. 修改web.xml配置
<servlet> <servlet-name>DocService</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.classnames</param-name> <param-value>org.glassfish.jersey.media.multipart.MultiPartFeature;es.ti.ws.ni.services.EnWS</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>DocService</servlet-name> <url-pattern>/rt/ni/verificar/*</url-pattern> </servlet-mapping> <servlet> <servlet-name>ExpService</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.classnames</param-name> <param-value>org.glassfish.jersey.media.multipart.MultiPartFeature;es.ti.ws.ni.exp.services.Enexp</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>ExpService</servlet-name> <url-pattern>/rt/ni/obtener/*</url-pattern> </servlet-mapping>
2. 修改资源类的@Path注解
将EnWS类的@Path改为空字符串:
@Path("") public class EnWS { @GET @Path("") public Response verificar(@QueryParam("request") String request) { // 业务逻辑 } }
同理,Enexp类的@Path也改为空字符串:
@Path("") public class Enexp { @GET @Path("") public Response obtener(@QueryParam("request") String request) { // 业务逻辑 } }
此时请求/rt/ni/verificar?request=...会被DocService处理,匹配到EnWS的方法;/rt/ni/obtener?request=...会被ExpService处理。
注意:方案二需要修改Java代码,不如方案一简洁,因此优先推荐方案一。
内容的提问来源于stack exchange,提问作者Sergio L
相关产品推荐
相关产品推荐

