Search code examples
jsfprimefacesconverterspicklist

How to write a custom converter for <p:pickList>


How can I write a custom converter when working with PrimeFaces components that use a list of POJO? My particular problem is with <p:pickList>

<p:pickList converter="????" value="#{bean.projects}" var="project" 
                             itemLabel="#{project.name}" itemValue="#{project}">

Without a converter I get java.lang.ClassCastException because JSF sets the submitted values with unconverted java.lang.String submitted values.


Solution

  • After research on how to write custom converter, here is the solution.
    1. create a Java Class that implement javax.faces.convert.Converter;

    public class ProjectConverter implements Converter{
    
       @EJB
       DocumentSBean sBean;
    
       public ProjectConverter(){
       }
    
       public Object getAsObject(FacesContext context, UIComponent component, String value){
         return sBean.getProjectById(value);
         //If u look below, I convert the object into a unique string, which is its id.
         //Therefore, I just need to write a method that query the object back from the 
         //database if given a id. getProjectById, is a method inside my Session Bean that
         //does what I just described
       }
    
       public String getAsString(FacesContext context, UIComponent component, Object value)     
       {
         return ((Project) value).getId().toString(); //--> convert to a unique string.
       }
    }
    

    2. Register your custom converter in faces-config.xml

    <converter>
        <converter-id>projectConverter</converter-id>
        <converter-class>org.xdrawing.converter.ProjectConverter</converter-class>
    </converter>
    

    3. So now inside Primefaces component, u just do converter="projectConverter". Note that projectConverter is the <convert-id> I just created. So to solve my problem above, I do this:

    <p:pickList converter="projectConverter" value="#{bean.projects}" var="project" 
                                itemLabel="#{project.name}" itemValue="#{project}">