【问题标题】:Null when calling managed bean via @ManagedBean通过@ManagedBean 调用托管bean 时为空
【发布时间】:2014-11-12 12:20:47
【问题描述】:

我在会话范围中有两个托管 bean。第一个是一个简单的元素列表。

@ManagedBean (name = TrainList.BEAN_NAME)
@SessionScoped
public class TrainList extends ListBasic<TrainObj> {    

    private static final long serialVersionUID = 1L;
    public static final String BEAN_NAME = "trainList";

    public TrainList ()  {
        super();
    }
}

Second 表示列表中特定记录的详细信息,在用户单击第一个列表中的记录后调用。

@ManagedBean (name = TrainForm.BEAN_NAME)
@SessionScoped
public class TrainForm extends TrainObj {
    private static final Logger logger = Logger.getLogger(TrainForm.class.getName());
    public static final String BEAN_NAME = "trainForm";

    @ManagedProperty(value = "#{trainList}")
    private TrainList trainList; /* + getter and setter */


    public TrainForm ()  {
        super();
    }

    public void refreshList(){
     if (trainList != null) {
            logger.debug(" trainlist is not null");
             trainList.refreshList();
        }
        else {
            logger.debug(" trainlist is NULL");
        }
}

所以列表 bean 在第二个之前被初始化。 但是从第二个访问第一个 bean 时仍然为空?

[2014-11-12 13:18] DEBUG [http-apr-8080-exec-7] - com.kropla.TrainForm.update(TrainForm.java:xx) - trainlist is NULL

怎么了?

[请不要投反对票 - 我已经搜索了一个答案,但没有找到合适/合适的答案]

我可以列出所有托管 bean (https://stackoverflow.com/a/15503044/2303190),并且此 bean 已在列表中。但为什么我会得到 null?

【问题讨论】:

  • 在@ManagedBean 中尝试使用 eager true
  • 仍然为空。看起来这个类从未被创建为 bean。但在其他类(具有类似架构)中,它可以正常工作。

标签: java jsf-2


【解决方案1】:

试着像这样得到豆子。我在我的应用程序中使用了下面的代码,但我使用的是@ViewScoped,你的是 SessionScoped,试试这个它可能会工作。

FacesContext context = FacesContext.getCurrentInstance();
TrainList trainList = context.getApplication().evaluateExpressionGet(context, "#{trainList}",TrainList.class);

【讨论】:

  • 我正在开发 Tomcat,不想包含另一个 jar 作为依赖项 (el-api.jar)
【解决方案2】:

似乎问题与从第一个初始化(调用)第二个bean的方式有关。

private String returnDetailPageName(TrainObj entityObj) {
        Map session = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
        TrainForm formBean = new TrainForm();
        formBean.setMe(entityObj); //setter for the entity vproperties
        session.put(formBeanName , formBean);
        return "goProdTraining"; //go to detail page
    }

这种调用 bean 的“会话”方式是创建未存储在 JSF 中的新 bean。 通过 ManagedProperty 更改调用 bean 属性可以使用 PostConstruct 将父 bean 分配给子 bean(以防止循环循环):

@ManagedBean (name = TrainList.BEAN_NAME)
@SessionScoped
public class TrainList extends ListBasic<TrainObj> {    

    private static final long serialVersionUID = 1L;
    public static final String BEAN_NAME = "trainList";

    public TrainList ()  { super();}

    @ManagedProperty (value = "#{trainForm}")
    private TrainForm trainForm; //with getter&setter

    @PostConstruct
    private void setChildBeanProperty(){
        this.trainForm.setTrainList(this);
    }
}


@ManagedBean (name = TrainForm.BEAN_NAME)
@SessionScoped
public class TrainForm extends TrainObj {
    private static final Logger logger = Logger.getLogger(TrainForm.class.getName());
    public static final String BEAN_NAME = "trainForm";

    private TrainList trainList; /* + getter and setter */

    public TrainForm ()  {
        super();
    }

    public void refreshList(){
     if (trainList != null) {
            logger.debug(" trainlist is not null");
             trainList.refreshList();
        }
        else {
            logger.debug(" trainlist is NULL");
        }
}

【讨论】:

    猜你喜欢
    • 2013-04-16
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 2015-05-16
    相关资源
    最近更新 更多