4

我有一个会话范围的 CDI 托管 bean:

@Named
@SessionScoped 
public class SampleBean implements Serializable {
    // ...
}

我需要在某个流程之后从会话中删除此 bean,为此我使用了以下代码,如本答案中所示:

ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.getSessionMap().remove("sampleBean");

但是,它不起作用,并且SampleBean仍然在会话中。
我错过了什么吗?

4

3 回答 3

9

与 JSF 托管 bean 不同,CDI 托管 bean 不直接按其托管 bean 名称存储在会话映射中。相反,它们由 CDI 管理器实现(Weld、OpenWebBeans 等)使用会话 ID 作为键存储在服务器内存中。

因此,您在那里使用的技巧不适用于 CDI 托管 bean。您需要寻找替代方法。在这种特殊情况下,正确的方法是使用@ConversationScoped而不是@SessionScoped. 在正确设计的 Web 应用程序中,永远不需要手动终止作用域。因此@SessionScoped,首先用于对话/流程已经是错误的。

于 2013-09-19T15:24:58.990 回答
0
@Inject
BeanManager beanManager;
.....
AlterableContext ctxSession = (AlterableContext) beanManager.getContext(SessionScoped.class);
for (Bean<?> bean : beanManager.getBeans(YourSessionBeanToBeDestroyedClass.class)) {
    Object instance = ctxSession.get(bean);
    if (instance != null)
        ctxSession.destroy(bean);
}
于 2021-09-23T11:50:13.150 回答
-1

还有这个 ?

FacesContext .getCurrentInstance() .getApplication() .createValueBinding( "#{yourBeanName}").setValue(FacesContext.getCurrentInstance(), null );

于 2015-04-13T01:39:57.160 回答