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

Java 如何在singleton jersey拦截器中使用RequestScope对象?,java,jersey,jax-rs,jersey-2.0,hk2,Java,Jersey,Jax Rs,Jersey 2.0,Hk2,jersey拦截器是在应用程序启动时构造的。因此,它的依赖项(在本例中)被注入到请求范围之外 问题是,密码是安全的,因此它们应该被注入请求范围。怎么做 @Provider @Priority(Priorities.ENTITY_CODER + 1) public class CryptInterceptor implements ReaderInterceptor, WriterInterceptor { @Inject @Named("ENC_CIPHER") private

jersey拦截器是在应用程序启动时构造的。因此,它的依赖项(在本例中)被注入到请求范围之外

问题是,密码是安全的,因此它们应该被注入请求范围。怎么做

@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一样--

现在很明显,hk2(泽西岛的DI)不能将RequestScope对象注入到单例拦截器中。它导致:

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);
对另一个也要这样做。但是请记住,当您访问它时,它将是一个代理实例,而不是密码实例

另请参见:


我在泽西岛学习代理文档时经历了一段艰难的时光。任何提示,这段代码在幕后做什么?
proxy
会创建一个动态代理。因此,每次您访问该服务时,它都是一个代理。
proxyForSameScope
只是说,如果父对象在同一个范围内,即请求范围内,不要将其作为代理,只使用真实对象。例如,现在它将是一个代理对象,但如果您尝试将其注入到资源类(默认情况下为请求范围)中,它将成为实际实例的代理对象。这篇文章中还有一篇关于动态代理的链接文章。如果您想了解代理在幕后是如何工作的,那么这也可能是一个很好的读物。代理在运行时除了在调用服务的方法时查找请求的服务外,实际上没有什么作用。这允许更改具有不同生命周期的作用域,即使注入服务(代理)的对象没有更改解决方案是正确的。但不幸的是,在我的案例中,由于完全无关的原因,它失败了。这是因为
java.lang.InstantiationException:javax.crypto.Cipher\u$$\ ujvstffc\u0
这意味着,没有什么比得上新密码()。因此,我必须将密码包装到CipherBox中,然后它就完成了。
bindFactory(EncCipherFactory.class)
        .proxy(true)
        .proxyForSameScope(false)
        .to(Cipher.class)
        .named("ENC_CIPHER")
        .in(RequestScoped.class);