泽西拦截器是在应用程序启动时构建的。因此,它的依赖项(在这种情况下为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.
答案 0 :(得分:2)
您需要代理服务。如果不这样,那么Jersey将尝试注入实际对象,并且在创建拦截器时没有请求。至于试图让拦截器本身请求范围,我不知道。不确定是否可能。
bindFactory(EncCipherFactory.class)
.proxy(true)
.proxyForSameScope(false)
.to(Cipher.class)
.named("ENC_CIPHER")
.in(RequestScoped.class);
同样对另一个做同样的事。但请记住,当您访问它时,它将是一个代理实例,而不是密码实例。
另见: