我必须以编程方式从 servlet 中查找由 CDI 管理的会话范围 bean。
到目前为止,我已经设法使用 BeanManager 实例查找默认范围的 bean。但是对于会话范围的 bean,查找失败并显示以下消息:
org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.enterprise.context.SessionScoped
org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:598)
org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:71)
org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:79)
de.eb.mdsd.prototype.server.SessionStuff$Proxy$_$$_WeldClientProxy.test(SessionStuff$Proxy$_$$_WeldClientProxy.java)
de.eb.mdsd.prototype.server.FooServlet.doGet(FooServlet.java:21)
javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
有没有办法手动设置活动会话范围?该应用程序当前在 JBoss 7 上运行,因此 CDI 实现是 Weld,但是最好使用不限于 Weld 的通用解决方案。
这是我到目前为止一直在使用的代码:
public class FooServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
final SessionStuff sessionStuff = lookup(SessionStuff.class);
sessionStuff.test();
}
private BeanManager getBeanManager() {
try {
return (BeanManager) InitialContext.doLookup("java:comp/BeanManager");
}
catch (final NamingException e) {
throw Exceptions.propagate(e);
}
}
@SuppressWarnings("unchecked")
private <T> T lookup(final Class<T> clazz) {
final BeanManager bm = getBeanManager();
final Iterator<Bean<?>> iter = bm.getBeans(clazz).iterator();
if (!iter.hasNext()) {
throw new IllegalStateException("CDI BeanManager cannot find an instance of requested type " + clazz.getName());
}
final Bean<T> bean = (Bean<T>) iter.next();
final CreationalContext<T> ctx = bm.createCreationalContext(bean);
return (T) bm.getReference(bean, clazz, ctx);
}
}