How to inject Grizzly Request into Jersey ContainerRequestFilter

怎甘沉沦 提交于 2020-01-11 07:11:28

问题


I have Jersey being provided by Grizzly.

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
    }
}

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.

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?


回答1:


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.

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: Not inside a request scope.

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.

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.

See Also:

  • Injecting Request Scoped Objects into Singleton Scoped Object with HK2 and Jersey


来源:https://stackoverflow.com/questions/37739868/how-to-inject-grizzly-request-into-jersey-containerrequestfilter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!