我已经查看了很多帖子,似乎没有什么能像我喜欢的那样工作。
我想从过滤器中将一个对象注入到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注入到我的网络资源中,那么一切都按预期工作。但是,如果调用我的提供者类ContainerRequestContext始终为null。
我似乎不知道为什么这不起作用。
Reagrds 纳斯
答案 0 :(得分:1)
问题在于,通过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 - 另见Dependency injection with Jersey 2.0
答案 1 :(得分: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进行任何其他输入。
此致 纳斯