Jersey:ContainerRequestFilter没有获得Context ServletRequest [英] Jersey: ContainerRequestFilter does not get Context ServletRequest

查看:133
本文介绍了Jersey:ContainerRequestFilter没有获得Context ServletRequest的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要查看此问题的完整代码,请参阅此github

To see the full code for this issue, please see this github

https://github.com/mobiusinversion/web-application

我还创建了这个Jersey Jira

I also created this Jersey Jira

https://java.net/jira/browse/JERSEY-2851

我正在使用Jersey 2.15处理 ContainerRequestFilter 。这是一个嵌入式Jetty应用程序,它被遮蔽成一个罐子。

I am working on a ContainerRequestFilter using Jersey 2.15. This is an embedded Jetty app which is shaded into a single jar.

在Jetty启动器(主类)中:

In the Jetty starter (main class):

public static void main(String[] args) throws Exception {
    ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
    context.setContextPath("/");
    Server jettyServer = new Server(10005);
    jettyServer.setHandler(context);
    ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/*");
    jerseyServlet.setInitOrder(0);
    jerseyServlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES, ServletConstants.COMPONENT_SCAN_ROOT);

    try {
        System.out.println("Starting Jetty");
        jettyServer.start();
        System.out.println("Jetty Started");
        jettyServer.join();
    } catch (Exception e) {
        System.out.println("Could not start server");
        e.printStackTrace();
    } finally {
        jettyServer.destroy();
    }
}

我有一个通过提供商包含的过滤器

I have a filter which is included via a provider

@Provider
public class ExampleProvider implements DynamicFeature {

    @Override
    public void configure(ResourceInfo resourceInfo, FeatureContext featureContext) {
        ExampleFilter exampleFilter = new ExampleFilter();
        featureContext.register(exampleFilter);
    }
}

然后在过滤器中:

public class ExampleFilter implements ContainerRequestFilter {

    private static final Logger logger = LoggerFactory.getLogger(ExampleFilter.class);

    @Context
    private HttpServletRequest servletRequest;

    @Override
    public void filter(ContainerRequestContext containerRequestContext) throws IOException {
        logger.info("IP ADDRESS " + servletRequest.getRemoteAddr());
        // ...
    }

}

但是这会产生 NullPointerException

Caused by: java.lang.NullPointerException: null
at com.example.filters.ExampleFilter.filter(ExampleFilter.java:29) 
at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:131) 
at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:67) 

我做错了什么以及如何解决这个问题?

What am I doing wrong and how do I fix this?

更新:包括为Jetty和Jersey指定的pom

UPDATE: Including pom entried for Jetty and Jersey

    <properties>
        <jersey.version>2.15</jersey.version>
        <jetty.version>9.2.6.v20141205</jetty.version>
    </properties>

    <!-- Jersey -->
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>${jersey.version}</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>${jersey.version}</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey</groupId>
        <artifactId>jersey-bom</artifactId>
        <version>${jersey.version}</version>
        <type>pom</type>
        <scope>compile</scope>
    </dependency>

    <!-- Jetty -->
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-server</artifactId>
        <version>${jetty.version}</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-servlet</artifactId>
        <version>${jetty.version}</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-servlets</artifactId>
        <version>${jetty.version}</version>
    </dependency>


推荐答案

错误在于你手动创建 ExampleRequestFilterProvider 中的 ExampleRequestLoggingFilter 的实例。依赖注入仅适用于由容器本身创建和管理的实例,例如 ExampleRequestFilterProvider 。这解释了为什么 @Context 注入在手动创建的实例中似乎不起作用。

The mistake was that you manually created an instance of ExampleRequestLoggingFilter inside the ExampleRequestFilterProvider. Dependency injection only works on instances created and managed by the container itself, such as the ExampleRequestFilterProvider. This explains why @Context injection didn't seem to work in your manually created instance.

解决方案是将注入点移动到 ExampleRequestFilterProvider ,然后将其传递给 ExampleRequestLoggingFilter 的构造函数。

A solution would be to move the injection point to the ExampleRequestFilterProvider and then pass it through to the constructor of ExampleRequestLoggingFilter.

@Provider
public class ExampleRequestFilterProvider implements DynamicFeature {

    @Context
    private HttpServletRequest request;

    @Override
    public void configure(ResourceInfo resourceInfo, FeatureContext featureContext) {
        ExampleRequestLoggingFilter exampleRequestLoggingFilter = new ExampleRequestLoggingFilter(request);
        featureContext.register(exampleRequestLoggingFilter);
    }

}

我在这里测试过(感谢Git项目!)它对我有用。

I tested it here (kudos to the Git project!) and it worked for me.

请注意,你在这里没有传递实际的 HttpServletRequest 实例,但是一个容器管理代理,它在每次方法调用时进一步委托给实际实例,所以这里没有什么可担心的完整性和线程安全。

Note that you're here not passing the actual HttpServletRequest instance, but a container managed proxy which delegates further to the actual instance on every method call, so there's nothing to worry as to integrity and threadsafety here.

这篇关于Jersey:ContainerRequestFilter没有获得Context ServletRequest的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆