Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在JSF2.0/2.1中用CDI替换@ManagedBean/@ViewScope_Jsf_Jsf 2_Cdi_View Scope - Fatal编程技术网

如何在JSF2.0/2.1中用CDI替换@ManagedBean/@ViewScope

如何在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

我目前正在使用RichFaces评估JavaEE6/JSF2.1

声明为

@ManagedBean
@ViewScoped
  • 获取ID集(以准备删除操作)
  • 通过JSF将显示一个确认弹出窗口
  • 如果用户确认,将调用delete方法并删除在步骤1中为其存储ID的行
  • 由于CDI bean没有ViewScope,我尝试将该bean声明为:

    @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");
        }
    
    }