How to create Primefaces radioButtons from List?

I want to create a set of Radiobuttons from a List of Objects #{item.items3} and store the selected object into #{cartBean.selectedChoice} . Now I don't really get the difference between the values needed for <f:selectItems> and <ui:repeat> . How does my code look. Any obvious mistakes so far?

<p:selectOneRadio id="myRadio" value="#{cartBean.selectedChoice}" layout="custom">
    <f:selectItems value="#{item.items3}"/>
</p:selectOneRadio>

<h:panelGrid columns="1">
    <ui:repeat var="choice" value="#{item.items3}" varStatus="choiceIndex">
        <p:radioButton id="choiceRadio" for=":iterateCategories:iterateItems:lightForm:myRadio" itemIndex="#{choiceIndex.index}" />#{choice.name}
    </ui:repeat>
</h:panelGrid>

At the moment I am getting the following Error:

20:58:52,397 INFO [javax.enterprise.resource.webcontainer.jsf.renderkit] (http-localhost-127.0.0.1-8080-1) WARNING: FacesMessage(s) have been enqueued, but may not have been displayed. sourceId=iterateCategories:0:iterateItems:2:lightForm:myRadio[severity=(ERROR 2), summary=(Conversion Error setting value 'huhu.model.generated.Item@3ae5e1dc' for 'null Converter'.), detail=(Conversion Error setting value 'huhu.model.generated.Item@3ae5e1dc' for 'null Converter'.)]

I don't understand, where there could be a conversion problem as only objects of the same class are dealt with.


JSF generates HTML. HTML is basically one large string. Non-string typed Java objects needs therefore to be converted to string. If a type is encountered for which either no builtin converter ( Number , Boolean and Enum ) nor a custom converter (a class implementing Converter ) is found, then the object's default toString() implementation will be used to print the complex Java object into the HTML output. If your object doesn't have this method overridden, then it will be the Object#toString() 's default implementation which is described in the javadoc:

The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character @ , and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:

getClass().getName() + '@' + Integer.toHexString(hashCode())

In your particular case, the generated HTML radio button element becomes the following:

<input type="radio" ... value="huhu.model.generated.Item@3ae5e1dc" />

(rightclick the page in browser and choose View Source to see it yourself)

Now, when this form is submitted, the very input value huhu.model.generated.Item@3ae5e1dc which is collected by request.getParameter() (which returns String !) has to be converted back to a concrete instance of your custom type Item . However, as there's apparently no converter been registered for the custom type (error message already hints this: "null converter"), JSF is unable to convert it back to Item and will throw this converter exception.

You should really be providing a custom converter which properly converts between Item and its unique String representation. More than often a technical ID (such as the autogenerated PK from the database) is been used as unique String representation. The converter would then look like as follows:

@FacesConverter(forClass=Item.class)
public class ItemConverter implements Converter {

    @Override
    public void getAsString(FacesContext context, UIComponent component, Object modelValue) throws ConverterException {
        // Write code to convert Item to its unique String representation. E.g.
        return String.valueOf(((Item) modelValue).getId());
    }

    @Override 
    public void getAsObject(FacesContext context, UIComponent component, Object submittedValue) throws ConverterException {
        // Write code to convert unique String representation of Item to concrete Item. E.g.
        return someItemService.find(Long.valueOf(submittedValue));
    }

}

Alternatively, you could use the SelectItemsConverter of the JSF utility library OmniFaces so that the converter will instead use the <f:selectItem(s)> as conversion basis. This way you don't need to create a custom converter for every custom Java type which you'd like to use in <f:selectItem(s)> . See also the SelectItemsConverter showcase page:

<p:selectOneRadio ... converter="omnifaces.SelectItemsConverter">
链接地址: http://www.djcxy.com/p/71658.html

上一篇: 在JSF中以编程方式发送几条消息

下一篇: 如何从List创建Primefaces radioButtons?