Jersey @Context注入HttpServletRequest失败及依赖适配问题咨询
嘿,我来帮你梳理下这个问题——你遇到的两个核心痛点:HttpServletRequest注入始终为null,还有版本升级后的IncompatibleClassChangeError,其实都是Jersey版本差异和依赖配置不当导致的,下面分两种场景给你解决方案:
一、如果你想继续用Jersey 1.19.3(原版本)
Jersey 1.x的ContainerRequestFilter字段注入@Context有时候会因为容器扫描或Bean管理的问题失效,换方法参数注入会更可靠,而且要保证依赖版本完全一致:
1. 修改过滤器代码
把HttpServletRequest作为filter方法的参数注入,而不是类字段:
import javax.ws.rs.core.Context; import javax.ws.rs.ext.Provider; import com.sun.jersey.spi.container.ContainerRequest; import com.sun.jersey.spi.container.ContainerRequestFilter; import javax.servlet.http.HttpServletRequest; @Provider public class MyFilter implements ContainerRequestFilter { @Override public ContainerRequest filter(ContainerRequest containerRequest, @Context HttpServletRequest httpRequest) { // 这里httpRequest就能正常获取了,比如拿客户端IP String clientIp = httpRequest.getRemoteAddr(); // 你的业务逻辑... return containerRequest; } }
2. 确保依赖版本统一
jersey-server和jersey-json必须用同一个版本(1.19.3),不要混用其他版本:
<dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-server</artifactId> <version>1.19.3</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-json</artifactId> <version>1.19.3</version> </dependency>
3. 确认过滤器被扫描到
如果是web.xml配置,要加扫描包的参数:
<servlet> <servlet-name>JerseyServlet</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>你的过滤器所在包路径</param-value> </init-param> </servlet>
二、推荐升级到Jersey 2.x(更稳定,功能更全)
Jersey 2.x和1.x是完全不同的架构,groupId从com.sun.jersey改成了org.glassfish.jersey,而且不能混合两个版本的依赖,这也是你之前升级时出IncompatibleClassChangeError的原因——你用了2.7的server和2.8的json组件,版本不一致导致冲突。
1. 统一所有Jersey 2.x依赖版本
所有Jersey相关依赖必须用同一个版本,比如选2.35(较新的稳定版):
<!-- Jersey核心服务依赖 --> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-server</artifactId> <version>2.35</version> </dependency> <!-- Servlet容器集成依赖 --> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet</artifactId> <version>2.35</version> </dependency> <!-- JSON处理用Jackson --> <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>2.35</version> </dependency>
2. 2.x版本的过滤器注入方式
Jersey 2.x的ContainerRequestFilter接口已经更新,注入方式有两种可选:
方式一:字段注入(需确保过滤器被Jersey管理)
import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.core.Context; import javax.ws.rs.ext.Provider; import javax.servlet.http.HttpServletRequest; @Provider public class MyFilter implements ContainerRequestFilter { @Context private HttpServletRequest httpRequest; @Override public void filter(ContainerRequestContext requestContext) { // 正常使用httpRequest,比如拿请求路径 String requestPath = httpRequest.getRequestURI(); // 你的业务逻辑... } }
方式二:方法参数注入(更稳妥,无需担心Bean管理)
import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.core.Context; import javax.ws.rs.ext.Provider; import javax.servlet.http.HttpServletRequest; @Provider public class MyFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext, @Context HttpServletRequest httpRequest) { // 直接使用httpRequest // 你的业务逻辑... } }
3. 注册/扫描过滤器
- 用web.xml配置的话:
<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>你的过滤器所在包路径</param-value> </init-param> </servlet>
- 用Java配置(
ResourceConfig)的话:
import org.glassfish.jersey.server.ResourceConfig; public class JerseyConfig extends ResourceConfig { public JerseyConfig() { // 扫描指定包下的所有Provider和资源 packages("你的过滤器所在包路径"); // 或者直接注册过滤器 register(MyFilter.class); } }
三、关于IncompatibleClassChangeError的说明
这个错误100%是依赖版本冲突导致的:要么混合了Jersey 1.x和2.x的依赖,要么同系列版本内组件版本不一致(比如你之前用2.7的server+2.8的json)。解决的核心就是:
- 彻底移除所有
com.sun.jersey开头的1.x依赖 - 所有
org.glassfish.jersey开头的2.x依赖版本必须完全一致
内容的提问来源于stack exchange,提问作者user1052610

