如何为两个URL配置不同Filter与Jersey Servlet及启动异常排查
问题分析与解决方案
首先看你遇到的问题:你在web.xml里配置了两个同名的Servlet(都是jersey),分别对应/v1/*和/v2/*的URL模式,并且各自指定了不同的请求过滤器。但JBoss启动时抛出了javax.naming.NameNotFoundException: com的异常。
核心原因
Servlet规范明确要求<servlet-name>必须是唯一的,你重复使用jersey作为两个Servlet的名称,会导致容器初始化时出现命名冲突。而Jersey的CDI扩展在处理重复命名的Servlet时,JNDI上下文查找逻辑会出现混乱,最终触发了你看到的异常。
修复步骤
只需要给两个Servlet设置不同的名称,再对应调整servlet-mapping里的关联名称即可,修改后的web.xml配置如下:
<!-- 对应/v1/*的Jersey Servlet,使用Filter1 --> <servlet> <servlet-name>jersey-v1</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name> <param-value>com.core.api.filter.Filter1</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jersey-v1</servlet-name> <url-pattern>/v1/*</url-pattern> </servlet-mapping> <!-- 对应/v2/*的Jersey Servlet,使用Filter2 --> <servlet> <servlet-name>jersey-v2</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name> <param-value>com.core.api.filter.Filter2</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jersey-v2</servlet-name> <url-pattern>/v2/*</url-pattern> </servlet-mapping>
额外说明
- 每个Servlet实例必须拥有唯一名称,容器通过这个名称区分不同的Servlet配置,重复名称会直接导致初始化上下文混乱,尤其是在Jersey这类依赖CDI/JNDI的框架中,更容易触发这类异常。
- 修改后,两个URL模式会分别绑定到各自的Servlet实例,各自的过滤器也会独立生效,不会再出现命名冲突问题。
内容的提问来源于stack exchange,提问作者Prakash Panjwani
相关产品推荐
相关产品推荐

