[英]Spring Jersey to inject ContainerRequestContext on request scoped class
我已經看了很多帖子,似乎沒有什么能像我喜歡的那樣正常工作。
我想從過濾器中將一個對象注入ContainerRequestContext屬性中,並稍后在其他類中檢索它。
這是我的過濾器:
@Priority(Priorities.AUTHENTICATION)
public class AuthorizationFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext containerRequestContext) throws IOException {
containerRequestContext.setProperty("myObject", new Object());
}
}
這是我要訪問ContainerRequestContext的類:
@Provider
public class SessionContextProvider implements ISessionContextProvider {
@Context
private ContainerRequestContext request;
@Override
public Object getSessionContext() {
return request.getProperty("mySessionContext");
}
}
和我的彈簧配置:
@Bean(name="sessionContextProvider")
@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
public ISessionContextProvider sessionContextProvider() {
return new SessionContextProvider();
}
如果將ContainerRequestContext注入到我的Web資源中,一切都會按預期進行。 但是,如果調用我的提供程序類,那么ContainerRequestContext始終為null。
我似乎不明白為什么這行不通。
雷格斯·喬納斯(Reagrds Jonas)
問題在於,通過Jersey / Spring集成,它使我們能夠成功地將Spring bean注入到Jersey組件中,但是反之則並非總是如此。
澤西島擁有自己的DI框架HK2 1 ,它負責處理帶有澤西島組件的注射。 借助Jersey Spring集成,Jersey將查找Spring Bean,並按原樣使用它,它不會注入任何依賴項,我想假設Spring應該自己處理注入。
話雖如此,如果您不需要 ISessionContextProvider
成為Spring bean,則可以將其設為HK2服務。 很簡單 如果您不需要任何特殊的初始化,只需讓HK2創建它即可。 這里一個簡單的配置
public JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(new AbstractBinder() {
bind(SessionContextProvider.class)
.to(ISessionContextProvider.class)
.in(RequestScoped.class);
});
}
}
就是這樣。 您有一個可注入的ISessionContextProvider
2 。
如果您需要ISessionContextProvider
提供程序作為Spring bean,那么另一種選擇是從Spring ApplicatinContext
獲取bean,並使用HK2的ApplicationContext
類似物ServiceLocator
自己明確地注入它。 為此,我們需要使用Factory
透明地完成所有工作,因此您仍然可以注入Bean,而無需在外部進行任何額外的工作
import javax.inject.Inject;
import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.api.ServiceLocator;
import org.springframework.context.ApplicationContext;
public class SessionContextProviderFactory
implements Factory<SessionContextProvider> {
private final ISessionContextProvider provider;
@Inject
public SessionContextProviderFactory(ApplicationContext ctx,
ServiceLocator locator) {
provider = ctx.getBean(ISessionContextProvider.class);
locator.inject(provider);
}
@Override
public ISessionContextProvider provide() {
return provider;
}
@Override
public void dispost(ISessionContextProvider provider) { /* noop */ }
}
然后只要注冊工廠
public JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(new AbstractBinder() {
bindFactory(SessionContextProviderFactory.class)
.to(ISessionContextProvider.class)
.in(RequestScoped.class);
});
}
}
1- HK2
2-另請參閱Jersey 2.0的依賴注入
我找到了解決方法。 我可以將Spring HttpServletRequest注入到我的AuthorizationFilter中,並在此上設置SessionContext。
@Autowired
private HttpServletRequest request;
....
request.setAttribute("mySessionContext", sessionContext);
然后,因為HttpServletRequest已知會彈出,並且在我的SessionContextProvider中通常代表相同的事物,所以我這樣做:
@Autowired
private HttpServletRequest request;
@Override
public SessionContext getSessionContext() {
return (SessionContext) request.getAttribute("mySessionContext");
}
我不認為這是最好的解決方案。 但這有效。 如果有更好的解決方案,請等peeskillet輸入其他信息。
問候喬納斯
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.