selectOneRadio的JSF转换错误

时间:2012-04-06 18:30:58

标签: java jsf web-applications

我有一个简单的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的键,与第一种情况相同。

有人能帮我理解我错过的东西吗?谢谢!

1 个答案:

答案 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;
}