首页 文章

如何将Grizzly请求注入Jersey ContainerRequestFilter

提问于
浏览
1

我有泽西由Grizzly提供 .

我有一个 ContainerRequestFilter 实现类 . 但是,此类为所有传入请求创建一次 . 因此这样做:

public class EndpointRequestFilter implements ContainerRequestFilter {
    @Context
    private org.glassfish.grizzly.http.server.Request requestContext;

    public void filter( ContainerRequestContext req ) throws IOException {
       // remove for sake of example
    }
}

requestContext 为空 . 我可以将上下文注入到被调用的实际 endpoints 中,但这相当粗糙和丑陋,对我来说真的没用;因为我想记录各种要求 . 理想情况下,希望在请求的ResponseFilter端获取此 Request 对象 .

必须有一种简单的方法来做到这一点 . 到目前为止,我看到的所有问题/答案都不适用于Grizzly或注入REST endpoints 调用的方法 . 我不想绕过所有数百种方法,只是因为我想获得IP地址!

那么这里的关键是什么?我错过了什么?

1 回答

  • 2

    我很惊讶你甚至让应用程序运行,以达到你可以发现请求为空的程度 . 每当我尝试运行它时,我会在启动时遇到异常,说没有请求范围,因此无法注入请求,这就是我的预期 . 虽然我无法重现NPE,但我认为这个解决方案仍然可以解决您的问题 .

    所以 Request 是一个请求范围的对象,因为它在每个请求上都会发生变化 . 但过滤器本质上是一个单身人士 . 所以你需要做的就是懒洋洋地检索它 . 为此,我们可以使用javax.inject.Provider作为惰性检索机制 .

    回到我的第一段中的这一点,这是我启动时的例外

    java.lang.IllegalStateException:不在请求范围内 .

    这是有道理的,因为 Request 需要与请求范围相关联,并且在启动时,没有 . 请求范围仅在请求期间出现 .

    那么使用 Provider 的原因是允许我们在存在请求范围时尝试抓取 Request .

    public static class Filter implements ContainerRequestFilter {
    
        @Context
        private javax.inject.Provider<Request> requestProvider;
    
        @Override
        public void filter(ContainerRequestContext requestContext) throws IOException {
            final Request request = requestProvider.get();
            System.out.println(request.getRemoteAddr());
        } 
    }
    

    我测试了这个,它按预期工作 .

    See Also:

相关问题