jax-rs在ContainerRequestFilter和ReaderInterceptor之间共享信息

时间:2018-10-25 16:58:47

标签: java jersey jax-rs jersey-2.0

我正在使用Jax-rs,并且在Filters中进行了一些逻辑处理,然后我想在ContainerRequestFilter(过滤器​​)和ReaderInterceptor(拦截器)。

我可以通过set/getProperties看到在过滤器和拦截器之间是可能的,但是在过滤器和拦截器之间是不可能的。

是否知道是否还有其他机制?

致谢。

2 个答案:

答案 0 :(得分:1)

您可以使用注入过滤器和拦截器的请求范围服务。例如

public interface RequestScopedService {
    void setSomething(Object something);
    Object getSomething();
}

public class RequestScopedServiceImpl implements RequestScopedService {
    @Override
    public void setSomething(Object something) {}

    @Override
    public Object getSomething() {}
}

使用接口是最佳实践,这就是为什么我在这里这样做。要配置它,请在AbstractBinder 1 中注册一个ResourceConfig

public class JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        register(new AbstractBinder() {
            @Override
            public void configure() {
                bind(RequestScopedServiceImpl.class)
                        .to(RequestScopedService.class)
                        .proxy(true)
                        .proxyForSameScope(false)
                        .in(RequestScoped.class);
            }
        });
    }
}

现在您可以将其注入过滤器和拦截器中。

public class MyFilter implements ContainerRequestFilter {
    private final RequestScopedService service;

    @Inject
    public MyFilter(RequestScopedService service) {
        this.service = service;
    }
}

public class MyInterceptor implements ReaderInterceptor {
    private final RequestScopedService service;

    @Inject
    public MyInterceptor(RequestScopedService service) {
        this.service = service;
    }
}

我们使用proxy()方法对其进行配置,因为该服务是一个请求范围服务(意味着将为每个请求创建一个新服务),并且过滤器和编写器拦截器均为单例。因此,我们需要它作为将呼叫转发到 2 引擎盖下的真实服务的代理。


1。如果您未使用ResourceConfig进行配置(也许正在使用web.xml),请同时参见my answer in "Dependency Injection with Jersey 2.0What exactly is the ResourceConfig class in Jersey 2?

2。您可以在this article

中了解更多信息

答案 1 :(得分:1)

因此,比using a separate service for this更简单的方法是将ContainerRequestContext注入ReaderInterceptor中。我们需要将其作为javax.inject.Provider注入,以便我们可以懒惰地检索它。如果我们不这样做,就会遇到范围问题,因为拦截器本质上是单例,并且请求上下文是请求范围的(意味着为每个请求创建一个新的)。

public static class MyInterceptor implements ReaderInterceptor {
    private final javax.inject.Provider<ContainerRequestContext> requestProvider;

    @Inject
    public MyInterceptor(javax.inject.Provider<ContainerRequestContext> requestProvider) {
        this.requestProvider = requestProvider;
    }

    @Override
    public Object aroundReadFrom(ReaderInterceptorContext readerInterceptorContext) throws IOException, WebApplicationException {
        ContainerRequestContext request = requestProvider.get();
        String prop = (String) request.getProperty("SomeProp");
    }
}

使用javax.inject.Provider,我们通过调用get()获得实际的服务。因为我们使用的是Provider,所以将从请求范围的上下文中检索服务,这意味着实例将与请求绑定。


1。有关更多信息,请参见Request Scoped Injection into a Singleton with Jersey