2012-04-06 70 views
1

我有一個簡單的JSF Web應用程序,如下所示。 Java類包含:selectOneRadio的JSF轉換錯誤

private String myString; 

public String getMyString() 
{ 
    return myString; 
} 

public void setMyString(String radioValue) 
{ 
    myString = someHashMap.get(radioValue); 
    doStuffWith(myString); 
} 

而JSF頁面的源代碼包含:

<h:form> 
<h:selectOneRadio id="topicSelectOneRadio" required="true" 
    requiredMessage="Choose a thing" 
    value="#{someBean.myString}"> 
    <f:selectItem itemValue="radioValue1" itemLabel="1"/> 
    <f:selectItem itemValue="radioValue2" itemLabel="2"/> 
</h:selectOneRadio> 
<p><h:commandButton value="Do it"/></p> 
</h:form> 

據我瞭解,從網頁中radioValueX串被在Java類作爲參數傳遞給的myString setter方法。所以,我想一步擴展它使用任何類:

private Foo myFoo; 

public Foo getMyFoo() 
{ 
    return myFoo; 
} 

public void setMyFoo(String radioValue) 
{ 
    myFoo = someHashMap.get(radioValue); 
    doStuffWith(myFoo); 
} 

<h:form> 
<h:selectOneRadio id="topicSelectOneRadio" required="true" 
    requiredMessage="Choose a thing" 
    value="#{someBean.myFoo}"> 
    <f:selectItem itemValue="radioValue1" itemLabel="1"/> 
    <f:selectItem itemValue="radioValue2" itemLabel="2"/> 
</h:selectOneRadio> 
<p><h:commandButton value="Do it"/></p> 
</h:form> 

不過,我得到以下錯誤:

Conversion Error setting value 'radioValue' for 'null Converter'. 

我不知道我瞭解需要進行何種「轉換」的地方。在這兩種情況下,單選按鈕中的字符串值都將用作參數,以將字符串值作爲參數的setter方法使用。誠然,在後一種情況下,它實際上是爲不是字符串的東西設置值,但是應該不重要,應該如何?我不想將後一種情況下的radioValueX字符串轉換爲任何其他類型,只是將它用作hashmap的關鍵字,與第一種情況相同。

任何人都可以幫我理解我錯過了什麼嗎?謝謝!

+2

作爲一個方面說明,你的對象目前defi ned打破了「bean」合同。屬性'myFoo'是'Foo'類型的對象,正如getter所暗示的那樣,或者是setter所隱含的'String'?通常應避免這種不對稱。 – 2012-04-06 18:43:45

+0

setter如何暗示它是一個字符串? setter使用String作爲參數,但它將對象設置爲Foo。也就是說,引用的HashMap的類型是 ......我忘了提及的東西。這是否會改變你的擔憂,還是我仍然誤解?謝謝。 – The111 2012-04-06 19:21:03

+2

通常,bean setter應該採用與要設置的字段相同類型的參數。這是「豆合同」。 – 2012-04-06 19:28:25

回答

4

JSF試圖在之前將您的String轉換爲Object調用setter。而且由於你沒有爲你的對象註冊轉換器,你會得到這個錯誤。

轉換在JSF的生命週期階段3(PROCESS VALIDATIONS)中執行。在第四階段(UPDATE MODEL VALUES)中調用setter。

您需要添加一個轉換器,使其工作:

import javax.faces.convert.Converter; 
... 
@FacesConverter("FooConverter") 
public class FooConverter implements Converter{ 
    @Override 
    public Object getAsObject(FacesContext context, UIComponent component, 
      String value) { 
    someHashMap.get(value); 
    } 
    @Override 
    public String getAsString(FacesContext context, UIComponent component, 
      Object value) { 
    // convert from Object to String 
    }  
} 

使用轉換器是這樣的:

<h:selectOneRadio id="topicSelectOneRadio" required="true" 
    requiredMessage="Choose a thing" 
    value="#{someBean.myFoo}"> 
    <f:converter converterId="FooConverter"/> 
    <f:selectItem itemValue="radioValue1" itemLabel="1"/> 
    <f:selectItem itemValue="radioValue2" itemLabel="2"/> 
</h:selectOneRadio> 

然後(如正確伊恩對你的問題的評論說)你應該改變你的二傳手,因爲你不需要在這裏的轉換了:

public void setMyFoo(Foo newFoo) 
{ 
    myFoo = newFoo; 
} 
+1

謝謝。這似乎有點過於複雜,但。我想知道是否有一個更簡單的方法,比如在我的Foo類中創建一個額外的「radioValue」屬性作爲radio值,然後讓setter方法在那裏設置myFoo屬性。我想這會和轉換器一樣直接做同樣的事情?我將不得不在稍後與您的版本一起嘗試。感謝您的解決方案。:-) – The111 2012-04-06 19:24:24