如何在JSF2.0/2.1中用CDI替换@ManagedBean/@ViewScope
我目前正在使用RichFaces评估JavaEE6/JSF2.1 声明为如何在JSF2.0/2.1中用CDI替换@ManagedBean/@ViewScope,jsf,jsf-2,cdi,view-scope,Jsf,Jsf 2,Cdi,View Scope,我目前正在使用RichFaces评估JavaEE6/JSF2.1 声明为 @ManagedBean @ViewScoped 获取ID集(以准备删除操作) 通过JSF将显示一个确认弹出窗口 如果用户确认,将调用delete方法并删除在步骤1中为其存储ID的行 由于CDI bean没有ViewScope,我尝试将该bean声明为: @Named @ConversationScoped 现在,处理在步骤3中失败。因为在步骤1中设置的值(已选中)不再可用 我必须使用Conversation.begi
@ManagedBean
@ViewScoped
@Named
@ConversationScoped
现在,处理在步骤3中失败。因为在步骤1中设置的值(已选中)不再可用
我必须使用Conversation.begin()
和Conversation.end()方法吗
如果是这样的话,哪里是调用它们的好地方?如果您可以升级到JSF2.2,请立即执行。它为CDI提供了本机注释
import javax.faces.view.ViewScoped;
import javax.inject.Named;
@Named
@ViewScoped
public class Bean implements Serializable {
// ...
}
或者,安装它自己的CDI兼容,包括一个工作的@PreDestroy
(在JSF@ViewScoped
上被破坏)
另一种选择是安装JSF2.0/2.1@ViewScoped
与CDI之间的透明桥梁。这只会将自动生成的请求参数添加到URL(就像@ConversationScoped
一样)
如果您确实需要使用@ConversationScoped
,那么您确实需要手动开始和结束它。在会话的最新步骤中,您需要在@PostConstruct
中插入a并调用begin()
,通常是一个重定向到新视图的操作方法
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Named;
@Named
@ConversationScoped
public class Bean implements Serializable {
@Inject
private Conversation conversation;
// ...
@PostConstruct
public void init() {
conversation.begin();
}
public String submit() {
// ...
conversation.end();
return "some.xhtml?faces-redirect=true";
}
}
另见:
将对话注入bean,如果对话是暂时的,则在@PostConstructor
方法中启动对话
删除记录后,结束对话并导航到目标页面。开始谈话时。这里有一个例子
public class BaseWebBean implements Serializable {
private final static Logger logger = LoggerFactory.getLogger(BaseWebBean.class);
@Inject
protected Conversation conversation;
@PostConstruct
protected void initBean(){
}
public void continueOrInitConversation() {
if (conversation.isTransient()) {
conversation.begin();
logger.trace("conversation with id {} has started by {}.", conversation.getId(), getClass().getName());
}
}
public void endConversationIfContinuing() {
if (!conversation.isTransient()) {
logger.trace("conversation with id {} has ended by {}.", conversation.getId(), getClass().getName());
conversation.end();
}
}
}
我认为您可以从CDI扩展中获益,创建自己的作用域,这样您就可以实现上下文并使用@NormalScope
- CDI在每次bean调用后激发一个事件
AfterBeanDiscovery
- 您可以使用CDI扩展来观察此事件,并添加上下文实现
- 在范围实施中,您可以:
- 使用
context
从FacesContext
ViewRoot
Map
按名称获取bean,并在每次ajax回调后返回
- 如果在
FacesContext
ViewRoot
映射中找不到第一步中的bean名称,请使用CreationalContext
要获得更深入的解释,我建议使用以下链接:您可以使用:
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
@Named
@ViewScoped
public class PageController implements Serializable {
private String value;
public void setValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void execute() {
setValue("value");
}
@PostConstruct
public void init() {
System.out.println("postcontructor");
}
}
有一个项目包含对Java EE堆栈功能的扩展:。它是Seam 3、Apache CODI的整合。除其他外,它还包括CDI中的@ViewScope。这是一篇旧文章,现在已达到1.3.0版感谢您的快速回复。未结束的对话会发生什么情况,例如用户只是导航到另一个页面?它在会话结束时过期(顺便说一句,就像@ViewScoped
bean)。请注意,会话范围由特定的请求参数(在Weld中,即cid
)标识,因此它的行为不像会话范围的bean。如果您使用该对话框创建一个新请求,即使旧会话尚未结束,也会启动一个新会话。供将来参考:在JSF 2.2中,核心JSF中有一个与CDI兼容的视图范围。对于JSF 2.1,您**不能**,这就是问题所在。因此,请加强您的答案,使其包含JSF2.2
public class BaseWebBean implements Serializable {
private final static Logger logger = LoggerFactory.getLogger(BaseWebBean.class);
@Inject
protected Conversation conversation;
@PostConstruct
protected void initBean(){
}
public void continueOrInitConversation() {
if (conversation.isTransient()) {
conversation.begin();
logger.trace("conversation with id {} has started by {}.", conversation.getId(), getClass().getName());
}
}
public void endConversationIfContinuing() {
if (!conversation.isTransient()) {
logger.trace("conversation with id {} has ended by {}.", conversation.getId(), getClass().getName());
conversation.end();
}
}
@ConversationScoped
@Named
public class yourBean extends BaseWebBean implements Serializable {
@PostConstruct
public void initBean() {
super.initBean();
continueOrInitConversation();
}
public String deleteRow(Row row)
{
/*delete your row here*/
endConversationIfContinuing();
return "yourDestinationPageAfter removal";
}
}
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
@Named
@ViewScoped
public class PageController implements Serializable {
private String value;
public void setValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void execute() {
setValue("value");
}
@PostConstruct
public void init() {
System.out.println("postcontructor");
}
}