Jersey:ContainerRequestFilter没有获得Context ServletRequest

时间:2015-04-30 18:14:01

标签: java jersey jetty ip-address servlet-filters

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

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

我也创造了这个泽西吉拉

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

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

在Jetty启动器(主类)中:

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();
    }
}

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

@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) 

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

更新:包括为Jetty和Jersey

委托的pom
    <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>

1 个答案:

答案 0 :(得分:13)

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

解决方案是将注入点移动到ExampleRequestFilterProvider,然后将其传递给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项目赞不绝口!)它对我有用。

请注意,您这里没有传递实际的HttpServletRequest实例,而是一个容器管理代理,它会在每次方法调用时进一步委托给实际实例,因此无需担心这里的诚信和线索安全。