我有一个简单的JSF Web应用程序,如下所示。 Java类包含:
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'.
我不确定我知道哪里需要进行任何“转换”。在这两种情况下,单选按钮的String值都被用作setter方法的参数,该方法将String值作为参数。是的,在后一种情况下,它实际上是为不是字符串的东西设置值,但这应该不重要,是吗?我不是试图将后一种情况下的radioValueX String转换为任何其他类型,只是将它用作hashmap的键,与第一种情况相同。
有人能帮我理解我错过的东西吗?谢谢!
答案 0 :(得分:4)
在调用setter之前,JSF会尝试将您的String
转换为Object
。由于您没有为对象注册转换器,因此会出现此错误。
转换在JSF的生命周期阶段3(PROCESS VALIDATIONS)中执行。在第4阶段(更新模型值)中调用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>
然后(正如Ian对你的问题的评论中所说的那样)你应该更改你的二传手,因为你不再需要这里的转换了:
public void setMyFoo(Foo newFoo)
{
myFoo = newFoo;
}