如何在singleton jersey拦截器中使用RequestScoped对象?

时间:2017-01-13 09:39:13

标签: java jersey jax-rs jersey-2.0 hk2

泽西拦截器是在应用程序启动时构建的。因此,它的依赖项(在这种情况下为Cipher)是从请求范围注入的。

问题是密码是stateful所以它们应该被注入请求范围。怎么做?

@Provider
@Priority(Priorities.ENTITY_CODER + 1)
public class CryptInterceptor implements ReaderInterceptor, WriterInterceptor {

    @Inject @Named("ENC_CIPHER")
    private Cipher encryptionCipher;
    @Inject @Named("DEC_CIPHER")
    private Cipher decryptionCipher;

    @Override
    public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
        InputStream inputStream = context.getInputStream();
        CipherInputStream cipherInputStream = new CipherInputStream(inputStream, decryptionCipher);
        context.setInputStream(cipherInputStream);
        return context.proceed();
    }

    @Override
    public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
        OutputStream outputStream = context.getOutputStream();
        CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, encryptionCipher);
        context.setOutputStream(cipherOutputStream);
        context.proceed();
    }
}

为每个新请求期望新的密码就像在RequestScope中注入它们一样 -

public class BootstrapBinder extends AbstractBinder {
  @Override
  protected void configure() {
    bindFactory(EncCipherFactory.class).to(Cipher.class).named("ENC_CIPHER").in(RequestScoped.class);
    bindFactory(DecCipherFactory.class).to(Cipher.class).named("DEC_CIPHER").in(RequestScoped.class);
  }
}

现在显然hk2(泽西的DI)无法在Singleton拦截器中注入RequestScoped对象。它导致:

java.lang.IllegalStateException: Not inside a request scope.

1 个答案:

答案 0 :(得分:2)

您需要代理服务。如果不这样,那么Jersey将尝试注入实际对象,并且在创建拦截器时没有请求。至于试图让拦截器本身请求范围,我不知道。不确定是否可能。

bindFactory(EncCipherFactory.class)
        .proxy(true)
        .proxyForSameScope(false)
        .to(Cipher.class)
        .named("ENC_CIPHER")
        .in(RequestScoped.class);

同样对另一个做同样的事。但请记住,当您访问它时,它将是一个代理实例,而不是密码实例。

另见: