因此,我在阅读有关相同组件的QA时,但我感觉缺少一些东西,因为我落后了一步。
在其中使用primefaces自动完成组件时,我什至无法打开页面。
其代码片段是:

<p:autoComplete value="#{indirizzoCtrl.selectedCodiceNazione}"
            completeMethod="#{indirizzoCtrl.completeNazione}"
            var="nazione" itemLabel="#{nazione.nome}"
            itemValue="#{nazione.codiceNazione}" />

Nazione是Pojo类,其中CodiceNazioneNome are两个String字段(请确保使用getter和setter)。 completeNazione是ManagedBean上返回List<Nazione>的方法。
查看BalusC的说明here,在我看来,我不需要任何转换器,因为itemValue和value属性都映射到字符串属性。
无论如何,当我打开包含此自动完成代码段的页面时,它会因以下错误而崩溃:
javax.el.PropertyNotFoundException: /Cliente/Indirizzo.xhtml @23,56 itemValue="#{nazione.codiceNazione}": itemValue="#{nazione.codiceNazione}": Property 'codiceNazione' not found on type java.lang.String

为什么会这样呢?我真的不明白。方法completeNazione甚至还没有调用,因此它不应该知道任何Nazione
它出什么问题了?

编辑:
按照建议,我尝试添加一个转换器,但仍然出现相同的错误。
这是我的转换器:
    public class NazioneConverter implements Converter {

    final static Logger log = Logger.getLogger(NazioneConverter.class);

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value.trim().equals("")) {
            return null;
        } else {
            try {
                IndirizzoRepository ir = new IndirizzoRepository();
                List<Nazione> nazioni = ir.getNazioneByName(value);
                if (nazioni.size()==1) return nazioni.get(0);
                else throw new Exception();

            } catch (Exception e) {
                String msg = "Errore di conversione";
                log.error(msg, e);
                throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, "Non è una nazione conosciuta"));
            }
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if (value == null || value.equals("")) {
            return "";
        } else {
            return String.valueOf(((Nazione) value).getNome());
        }
    }

}

现在视图中的组件如下所示:
<p:autoComplete value="#{indirizzoCtrl.indirizzo.nazione.codiceNazione}"
            completeMethod="#{indirizzoCtrl.completeNazione}"
            var="nazione" itemLabel="#{nazione.nome}" converter="#{nazioneConverter}"
            itemValue="#{nazione.codiceNazione}" forceSelection="true"  />

但仍然不起作用。甚至没有调用该转换器:我将其注册在我的faces-config.xml文件中。
我也像在primefaces展示柜中一样尝试了itemValue =“#{nazione}”,但是问题变成了ItemLabel属性,映射到nazione.nome
我究竟做错了什么?

最佳答案

这对我有用:

//Converter
@FacesConverter(value="MarcaConverter")
public class MarcaConverter implements Converter{
    MarcaDAO marcaDAO;
    public Object getAsObject(FacesContext contet, UIComponent component, String value) {
        if(value==null || value.equals(""))
            return null;
        try{
            int id = Integer.parseInt(value);
            return marcaDAO.findMarcaById(id);
        }catch (Exception e) {
            e.printStackTrace();
            throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Marca no válida", ""));
        }
    }

    public String getAsString(FacesContext contet, UIComponent component, Object value) {
        if(value==null || value.equals(""))
            return null;
        return String.valueOf(((Marca)value).getCodigoMarca());
    }
}




//--------------------------------------
//Bean
@ManagedBean
@ViewScoped
public class MyBeans implements Serializable{
    private Marca marca;
    ...
    public Marca getMarca(){
        return marca;
    }
    public void setMarca(Marca m){
        marca=m;
    }
    ...
    public List<Marca> obtenerMarcasVehiculos(String s) {
        List<Marca> marcas,smarcas=new ArrayList<Marca>();
        try{
            marcas= marcaDAO.findAllMarcas();
            if(s.trim().equals("")) return marcas;
            for(Marca m:marcas)
                if (m.getNombreMarca().toString().contains(s) || m.getNombreMarca().toLowerCase().contains(s.toLowerCase())) {
                    smarcas.add(m);
                }
            return smarcas;
        }catch(Exception e){
            //JsfUtil.showFacesMsg(e,"Error al obtener las marcas de veh&iacute;culos","",FacesMessage.SEVERITY_WARN);
            e.printStackTrace();
            JsfUtil.lanzarException(e);
            return null;
        }
    }


//-----------------------------------------
//*.xhtml page
...
    <p:autoComplete
       id="cbxMarca" value="#{myBean.marca}" size="40"
       converter="MarcaConverter"
       completeMethod="#{myBean.obtenerMarcasVehiculos}"
       var="m" itemLabel="#{m.nombreMarca}" itemValue="#{m}"
       forceSelection="true" dropdown="true"
       required="true" scrollHeight="200">
    </p:autoComplete>
...

//-----------------------------------------
//Class Marca
public class Marca implements Serializable{
       private static final long serialVersionUID = 1L;

    private Integer codigoMarca;
    private String nombreMarca;
        ...

09-25 19:30