如何在单例球衣拦截器中使用 RequestScoped 对象?

How to use RequestScoped objects within singleton jersey interceptor?

球衣拦截器是在应用程序启动时构建的。因此它的依赖项(Ciphers 在这种情况下)被注入到请求范围之外。

问题是密码 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.

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

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

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

另请参阅: