2011-12-30 45 views
1

的facelet代码:JSF F:使用列表错误selectItems的

<h:selectOneMenu id = "country" label = "country" value = "#{beanController.countryResidence}"> 
    <f:selectItems value = "#{countries.countries}" /> 
</h:selectOneMenu> 

bean代码:

@ManagedBean(eager=true, name = "countries") 
@ApplicationScoped 
public class CountriesConstants { 
     private List<SelectItem> countries; 
     public CountriesConstants(){ 
      countries.add(new SelectItem("DE", "Germany")); 
      countries.add(new SelectItem("JA", "Japan")); 
      countries.add(new SelectItem("RU", "Russia")); 
      countries.add(new SelectItem("US", "United States")); 
     } 
     public List<SelectItem> getCountries() { 
      return countries; 
     } 
     public void setCountries(List<SelectItem> countries) { 
      this.countries = countries; 
     } 
} 

的错误

严重:异常而加载的应用程序

SEVERE: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: java.lang.RuntimeException: com.sun.faces.mgbean.ManagedBeanCreationException: Cant instantiate class: com.mysite.util.CountriesConstants. 

我跟着一些教程一步一步,但我不断收到此错误。我尝试使列表静态并初始化静态块中的值,但我得到相同的错误。

编辑:

Bean代码

@ManagedBean(eager=true, name="constants") 
@ApplicationScoped 
public class Constants { 

    public static final String VALIDATE_DETAILED = "detailed"; 
    public static final List<SelectItem> countries; 

    static{ 
     countries = new ArrayList<SelectItem>(); 
     countries.add(new SelectItem("DE", "Germany")); 
     countries.add(new SelectItem("JA", "Japan")); 
     countries.add(new SelectItem("RU", "Russia")); 
     countries.add(new SelectItem("US", "United States")); 
    } 

    public List<SelectItem> getCountries() { 
     return countries; 
    } 
} 

这似乎是工作,但我觉得很奇怪,我可以用非静态方法访问静态属性。如果我删除getCOuntries()方法错误说没有国家属性存在被抛出。

+0

当发现异常时,请始终查看堆栈跟踪的最底部。你有一个'NullPointerException'这是非常自我解释。 – BalusC 2011-12-31 20:40:13

回答

2

在bean的构造函数,你必须先创建你的列表,试试这个:

public CountriesConstants(){ 
    countries = new LinkedList<SelectItem>(); 
    countries.add(new SelectItem("DE", "Germany")); 
    countries.add(new SelectItem("JA", "Japan")); 
    countries.add(new SelectItem("RU", "Russia")); 
    countries.add(new SelectItem("US", "United States")); 
} 

此外,您<f:selectItems>标签应该有更多的属性。事情是这样的:

<f:selectItems value="#{countries.countries}" var="c" itemLabel="#{c.name}" itemValue="#{c.id}" /> 

UPDATE:假设你有以下控制器

@ManagedBean 
@RequestScoped 
public class BeanController { 
    private String countryResidence; 
} 
+0

如果国家列表已经包含SelectItem实例,为什么我应该指定_itemLabel_和_itemValue_? – Ionut 2011-12-30 19:44:29

+0

它似乎工作得很好,没有任何其他属性。我也检查了源代码,结果是所需的。谢谢! – Ionut 2011-12-30 20:12:43

+0

不客气! :) – 2011-12-30 20:13:30

2

初始化您的ArrayList第一

private List<SelectItem> countries = new ArrayList<SelectItem>(); 

你的facelets代码似乎罚款

2
private final List<SelectItem> countries = new ArrayList<SelectItem>(); 

如果想要使国家对象不再被实例化,请初始化并声明List为“final”。最好使用final来提高代码的可读性。

+0

嗯,你确定这是必要的吗?由于这个bean有'@ ApplicationScoped',只要没有额外的调用来重新初始化这个列表,我认为它在整个应用程序的生命周期中都会保持不变。 – 2011-12-30 19:38:41

+0

这当然不是必要的,但我会为它确定一个不可变的列表。如果它也是最终的,那么这是读代码的额外保证和意图声明。 – 2011-12-31 11:50:29