You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jersey @Context注入HttpServletRequest失败及依赖适配问题咨询

解决Jersey过滤器中@Context注入HttpServletRequest为null及依赖冲突问题

嘿,我来帮你梳理下这个问题——你遇到的两个核心痛点: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:13:54