2010-09-22 68 views
2

使用NetBeans,我生成了Hibernate映射文件和一組POJO。我還從實體類(生成的POJO)生成了一組JSF頁面。JSF生成的頁面和實體selectOneMenu

現在,我試圖添加一個下拉菜單,使我能夠選擇其中一個參與者。

<h:selectOneMenu value="#{measurementController.sensor}"> 
    <f:selectItems value="#{sensorController.itemsAvailableSelectOne}" /> 
</h:selectOneMenu> 

getItemsAvailableSelectOne()調用此方法:

public static SelectItem[] getSelectItems(List<?> entities, boolean selectOne) { 
    int size = selectOne ? entities.size() + 1 : entities.size(); 
    SelectItem[] items = new SelectItem[size]; 
    int i = 0; 
    if (selectOne) { 
     items[0] = new SelectItem("", "---"); 
     i++; 
    } 
    for (Object x : entities) { 
     items[i++] = new SelectItem(x, x.toString()); 
    } 
    return items; 
} 

在measurementController類我有這樣的:

private Sensor sensor; 

public Sensor getSensor() { 
    return this.sensor; 
} 

public void setSensor(Sensor sensor) { 
    this.sensor = sensor; 
} 

無論我做什麼,我得到Validation Error: Value is not valid錯誤,當我選擇的任何條目下拉式菜單。爲什麼?

我有一種感覺,我失去了一些非常明顯的東西,但我無法看到它。

編輯:

挖掘低谷生成的代碼,我發現一個現有的轉換器類:

@FacesConverter(forClass=Sensor.class) 
public static class SensorControllerConverter implements Converter { 

    public Object getAsObject(FacesContext facesContext, UIComponent component, String value) { 
     if (value == null || value.length() == 0) { 
      return null; 
     } 
     SensorController controller = (SensorController)facesContext.getApplication().getELResolver(). 
       getValue(facesContext.getELContext(), null, "sensorController"); 
     return controller.ejbFacade.find(getKey(value)); 
    } 

    java.lang.Integer getKey(String value) { 
     java.lang.Integer key; 
     key = Integer.valueOf(value); 
     return key; 
    } 

    String getStringKey(java.lang.Integer value) { 
     StringBuffer sb = new StringBuffer(); 
     sb.append(value); 
     return sb.toString(); 
    } 

    public String getAsString(FacesContext facesContext, UIComponent component, Object object) { 
     if (object == null) { 
      return null; 
     } 
     if (object instanceof Sensor) { 
      Sensor o = (Sensor) object; 
      return getStringKey(o.getIdSensor()); 
     } else { 
      throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: "+SensorController.class.getName()); 
     } 
    } 

} 

當我踏上槽這一切似乎做工精細的調試器的代碼。首先調用getAsObject方法,將所選項目作爲參數,返回值爲Sensor對象。

然後調用返回null(存儲在measurementController類中的當前值)的getSensor()方法。

最後,調用下拉菜單中的每個項目的getAsString()方法。我認爲這是渲染響應階段的一部分,與驗證無關。

回答

2

Validation Error: Value is not valid

<h:selectOneMenu>的情況下,你可以得到,只要所選擇的項目不匹配任何在列表中每Object#equals()合同提供的項目該驗證錯誤。基本上,歸結起來,sensor.equals(selectItem.getValue())從未返回true列表中的任何SelectItem項目。如果Sensor類的equals()方法沒有實施或執行不力,就會發生這種情況。

+0

我不敢相信我已經浪費了三天的時間了!我怎麼能這麼愚蠢。我沒有實現equals方法。更糟糕的是 - 在我看來,驗證器必須比較兩個Sensor實例,並且我實現了equals方法 - 通過引用而不是按值比較Integer。感謝一堆提示。 – skajfes 2010-09-23 20:24:23

+0

不客氣。你可以在[這個答案]中找到一些提示(http://stackoverflow.com/questions/3181339/right-way-to-implement-equals-contract/3181374#3181374)。 – BalusC 2010-09-23 20:34:17

1

您需要定義一個轉換器將對象Sensor轉換爲String,反之亦然。

此轉換器將通過JSF用來轉換SensorString時,頁面將呈現,並且它也將被用於從String轉換爲Sensor當值將在measurementController豆來設置,並在JSF組件樹結構。


首先,定義一個轉換器,它將實現 javax.faces.convert.Converter接口。在這個類中,定義兩個方法 getAsObject()getAsString()。它們用於進行轉換。

然後,在faces-config.xml文件中註冊該轉換器:

<converter> 
    <converter-id>SensorConverter</converter-id> 
    <converter-class>my.application.SensorConverter</converter-class>  
</converter> 

最後,你還可以定義爲一個特定的類的自動轉換器(在這種情況下,將不再需要最後一步):

<converter> 
    <converter-for-class>foo.bar.Sensor</converter-for-class> 
    <converter-class>my.application.SensorConverter</converter-class> 
</converter> 

最後,在您的<h:selectOneMenu/>組件中使用<f:converter id="SensorConverter"/>converterId="SensorConverter"

有關轉換和驗證的更多信息,請參閱here

+0

感謝您的快速響應。儘管如此,我只有一個問題。挖槽生成的代碼我發現它已經存在一個用於傳感器的Converter類,但它不起作用。我將使用代碼編輯問題.... – skajfes 2010-09-23 05:20:18

+0

註冊轉換器的JSF 2.0方法使用'@ FacesConverter'註釋。順便說一下,如果沒有合適的轉換器,那麼在驗證發生之前,OP寧可得到一個轉換錯誤,如'轉換錯誤設置值[email protected]'爲'null Converter'。 – BalusC 2010-09-23 20:43:20