2012-04-06 7 views
1

Ich habe eine einfache JSF Web App wie folgt. Die Java-Klasse enthält:JSF Conversion Error mit selectOneRadio

private String myString; 

public String getMyString() 
{ 
    return myString; 
} 

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

Und die JSF-Seite Quelle enthält:

<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> 

Wie ich es verstehe, ist die radioValueX Zeichenfolge von der Webseite als Parameter an das myString in der Java-Klasse verwendet wird, Setter-Methode. Also wollte ich es noch einen Schritt weiter verlängern jede Klasse zu verwenden:

private Foo myFoo; 

public Foo getMyFoo() 
{ 
    return myFoo; 
} 

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

und

<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> 

Allerdings bekomme ich folgende Fehlermeldung:

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

Ich bin nicht sicher, ob ich zu verstehen, wo irgendeine Art von "Umwandlung" stattfinden muss. In beiden Fällen wird der String-Wert aus dem Optionsfeld als Parameter für eine Setter-Methode verwendet, die einen String-Wert als Parameter verwendet. Richtig, im letzteren Fall wird der Wert für etwas gesetzt, das kein String ist, aber das sollte nicht wichtig sein, oder? Ich versuche nicht, den radioValueX-String im letzteren Fall in irgendeinen anderen Typ zu konvertieren, sondern benutze ihn als Schlüssel für eine Hash-Mappe, genau wie im ersten Fall.

Kann mir jemand helfen zu verstehen, was ich vermisse? Vielen Dank!

+2

Als Randnotiz, dein Objekt wie derzeit defi ned bricht den "Bohnen" -Vertrag. Ist die Eigenschaft 'myFoo' ein Objekt vom Typ' Foo', wie es vom Getter impliziert wird, oder ein 'String' wie vom Setter impliziert? Diese Art von Asymmetrie sollte generell vermieden werden. –

+0

Wie bedeutet der Setzer, dass es ein String ist? Der Setter verwendet einen String als Parameter, aber er setzt das Objekt als Foo. Das heißt, die referenzierte HashMap ist vom Typ ... etwas, das ich vergessen zu erwähnen. Ändert das deine Besorgnis oder bin ich immer noch falsch? Vielen Dank. – The111

+2

Normalerweise sollten Bean-Setter einen Parameter des gleichen Typs wie das einzustellende Feld verwenden. Das ist der "Bohnen-Vertrag". –

Antwort

4

JSF versucht, Ihre String zu Objectvor der Setter wird konvertiert. Und da Sie für Ihr Objekt keinen Konverter registriert haben, erhalten Sie diesen Fehler.

Die Konvertierung wird in JSFs Lebenszyklusphase 3 (PROCESS VALIDATIONS) durchgeführt. Die Setter werden in Phase 4 (UPDATE MODEL VALUES) aufgerufen.

Sie benötigen einen Konverter hinzuzufügen, damit es funktioniert:

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 
    }  
} 

Verwenden Sie den Konverter auf diese Weise:

<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> 

Dann (wie richtig in Ians Kommentar zu Ihrer Frage angegeben) Sie ändern sollten Dein Setzer da du die Konvertierung hier nicht mehr benötigst:

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

Danke. Das erscheint allerdings etwas übermäßig komplex. Ich frage mich, ob es einen einfacheren Weg gibt, wie zum Beispiel das Erstellen einer zusätzlichen "radioValue" -Eigenschaft in meiner Foo-Klasse für den Radio-Wert, und dann setzen Sie die Setter-Methode dort auch die myFoo-Eigenschaft. Ich nehme an, das würde das selbe tun wie der Konverter nur direkter? Ich werde es später zusammen mit deiner Version ausprobieren müssen. Danke für deine Lösung.:-) – The111