如何将 Grizzly 请求注入 Jersey ContainerRequestFilter
我有灰熊提供的球衣.
我有一个 ContainerRequestFilter
实现类.但是,此类为所有传入请求创建一次.因此这样做:
I have a ContainerRequestFilter
implementation class. However this class is created once for all incoming requests. Therefore doing this:
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
为空.我可以将上下文注入到被调用的实际端点中,但这相当粗糙和丑陋,对我来说真的没有用;因为我希望记录各种请求.理想情况下,希望在请求的 ResponseFilter 端获取此 Request
对象.
The requestContext
is null. I can inject the context into the actual endpoint being called, but that is rather crude and ugly and really no use to me; as i wish to log various requests. Ideally would like to get at this Request
object at the ResponseFilter side of the request.
必须有一个简单的方法来做到这一点.到目前为止,我看到的所有问题/答案都不适用于 Grizzly 或注入 REST 端点调用的方法.我不希望仅仅因为我想获取 IP 地址而绕过我在调用中添加这个的所有数百种方法!
There has to be an easy way of doing this. All the questions/answers I have seen thus far doesn't work for Grizzly or injects at the method being called by the REST endpoint. I don't wish to go around all my hundreds of methods adding this in call just because I want to get the IP address!
那么这里的关键是什么?我错过了什么?
So what is the key here? What am I missing?
推荐答案
我很惊讶你甚至让应用程序运行,直到你可以发现请求为空的地步.每当我尝试运行它时,我都会在启动时遇到异常,说没有请求范围,因此无法注入请求,这是我所期望的.虽然我无法重现 NPE,但我认为这个解决方案仍然可以解决您的问题.
I'm surprised you even got the app running, to get to the point where you could find out that request is null. Whenever I tried to run it, I would get an exception on start up, saying that there is no request scope, so the request can't be injected, which is what I expected. Though I couldn't reproduce the NPE, I'm thinking this solution will still solve your problem.
所以 Request
是一个请求范围的对象,因为它会随着每个请求而改变.但是过滤器本质上是一个单例.所以你需要做的是懒惰地检索它.为此,我们可以使用 javax.inject.Provider
,作为一种惰性检索机制.
So the Request
is a request scoped object, as it changes on every request. But the filter is by its nature, a singleton. So what you need to do, is lazily retrieve it. For that, we can use javax.inject.Provider
, as a lazy retrieval mechanism.
回到我第一段的重点,这是我在启动时遇到的异常
Going back to the point in my first paragraph, this was the exception I got on start up
java.lang.IllegalStateException:不在请求范围内.
java.lang.IllegalStateException: Not inside a request scope.
这是有道理的,因为 Request
需要与请求范围相关联,而在启动时,没有.请求范围仅在请求期间存在.
This makes sense, as the Request
need to be associated with a request scope, and on start up, there is none. A request scope is only present during a request.
所以使用 Provider
的作用是让我们在存在请求范围时尝试获取 Request
.
So what using the Provider
does, is allow us to try and grab the Request
when there is a request scope present.
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());
}
}
我已经对此进行了测试,它按预期工作.
I've tested this and it works as expected.
另请参阅:
- 使用 HK2 将请求范围对象注入单例范围对象和泽西岛
相关文章