如何为<p:pickList>编写自定义转换器

Tha*_*ham 21 jsf converter primefaces picklist

在使用使用POJO列表的PrimeFaces组件时,如何编写自定义转换器?我的特殊问题是<p:pickList>

<p:pickList converter="????" value="#{bean.projects}" var="project" 
                             itemLabel="#{project.name}" itemValue="#{project}">
Run Code Online (Sandbox Code Playgroud)

我没有转换器,java.lang.ClassCastException因为JSF使用未转换的java.lang.String提交值设置提交的值.

Bra*_*cha 39

有可能,没有其他数据库访问,但我不知道最好的方法.我使用非常特殊的转换器,仅适用于选项列表.试试这个:

@FacesConverter(value = "primeFacesPickListConverter")public class PrimeFacesPickListConverter implements Converter {
@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
    Object ret = null;
    if (arg1 instanceof PickList) {
        Object dualList = ((PickList) arg1).getValue();
        DualListModel dl = (DualListModel) dualList;
        for (Object o : dl.getSource()) {
            String id = "" + ((Project) o).getId();
            if (arg2.equals(id)) {
                ret = o;
                break;
            }
        }
        if (ret == null)
            for (Object o : dl.getTarget()) {
                String id = "" + ((Project) o).getId();
                if (arg2.equals(id)) {
                    ret = o;
                    break;
                }
            }
    }
    return ret;
}

@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
    String str = "";
    if (arg2 instanceof Project) {
        str = "" + ((Project) arg2).getId();
    }
    return str;
}
Run Code Online (Sandbox Code Playgroud)

和领料单:

<p:pickList converter="primeFacesPickListConverter" value="#{bean.projects}" var="project" 
                        itemLabel="#{project.name}" itemValue="#{project}">
Run Code Online (Sandbox Code Playgroud)

工作对我来说,改进是必要的.

  • 这是最好的解决方案.在转换器中查询数据库是最糟糕的事情,即在源列表中添加1000个项目,至少有一个嵌套实体,看看会发生什么;) (4认同)

Tha*_*ham 18

在研究了如何编写自定义转换器之后,这是解决方案.
1.创建一个实现的Java类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.
   }
}
Run Code Online (Sandbox Code Playgroud)

2.注册您的自定义转换器 faces-config.xml

<converter>
    <converter-id>projectConverter</converter-id>
    <converter-class>org.xdrawing.converter.ProjectConverter</converter-class>
</converter>
Run Code Online (Sandbox Code Playgroud)

所以现在在Primefaces组件中,你就是这样做的converter="projectConverter".请注意,这projectConverter<convert-id>我刚刚创建的.所以为了解决上面的问题,我这样做:

<p:pickList converter="projectConverter" value="#{bean.projects}" var="project" 
                            itemLabel="#{project.name}" itemValue="#{project}">
Run Code Online (Sandbox Code Playgroud)


Rar*_*ean 5

是的,您可以编写一个转换器来序列化/反序列化选项列表中的对象,如下所示:

@FacesConverter(value="PositionMetricConverter")
public class PositionMetricConverter implements Converter {

    private static final Logger log = Logger.getLogger(PositionMetricConverter.class.getName());

    @Override
    public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value) {
        try {
            byte[] data = Base64.decodeBase64(value);
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data));
            Object o = ois.readObject();
            ois.close();
            return o;
        } catch (Exception e) {
            log.log(Level.SEVERE, "Unable to decode PositionMetric!", e);
            return null;
        }
    }

    @Override
    public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(value);
            oos.close();

            return Base64.encodeBase64String(baos.toByteArray());
        } catch (IOException e) {
            log.log(Level.SEVERE, "Unable to encode PositionMetric!", e);
            return "";
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

然后将此转换器应用于您的选项列表,如下所示:

<p:pickList converter="PositionMetricConverter" value="#{bean.positionMetrics}" 
    var="positionMetric" itemLabel="#{positionMetric.name}" itemValue="#{positionMetric}"/>
Run Code Online (Sandbox Code Playgroud)

并确保您的对象是可序列化的.