2011-12-30 46 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