Primefaces <;p:选择一个功能表>&书信电报;f:选择项目>;在itemLabel中显示toString()

Primefaces <;p:选择一个功能表>&书信电报;f:选择项目>;在itemLabel中显示toString(),primefaces,converter,jsf-2.2,Primefaces,Converter,Jsf 2.2,当我使用f:selectItems时,itemLabel不显示属性DescriptaO,而是显示toString()。我做了一些研究,但问题仍然存在 我做错了什么?有什么想法吗 我有一个Tipo类,如下所示: public class Tipo implements Serializable{ /** * */ private static final long serialVersionUID = -763536865855419703L;

当我使用f:selectItems时,itemLabel不显示属性DescriptaO,而是显示toString()。我做了一些研究,但问题仍然存在

我做错了什么?有什么想法吗

我有一个Tipo类,如下所示:

   public class Tipo implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = -763536865855419703L;
    // descrição do tipo
    private String descricao;
    // código do tipo
    private Long tipoId;


    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException cnse) {
            return null;
        }
    }

    public Tipo(Long id) {
        this.tipoId = id;
    }

    public Tipo() {

    }

    public String getDescricao() {
        return descricao;
    }

    public Long getTipoId() {
        return tipoId;
    }

    public void setDescricao(String umaDesc) {
        this.descricao = umaDesc;
    }

    public void setTipoId(Long id) {
        this.tipoId = id;
    }




    public String toString() {
        return " ID=" + this.getTipoId() + ", Descricao=" + this.getDescricao();
    }

    @Override
    public boolean equals(Object other){
        return (other != null && getClass() == other.getClass() && tipoId != null) 
                ? tipoId.equals(((Tipo) other).tipoId) : (other == this);
    }

    @Override
    public int hashCode() {
        return (tipoId != null) 
                ? (getClass().hashCode() + tipoId.hashCode()) : super.hashCode();
    }


}
和TipoDAOImpl:

    public class TipoDAOImpl extends NamedParameterJdbcDaoSupport implements TipoDAO, Serializable {

    private static final long serialVersionUID = 8698127647660788120L;
    private SimpleJdbcInsert sji;
    @Value("#{queries.sql03}")
    private String sql03;
    @Value("#{queries.sql04}")
    private String sql04;

@Override
    public List<Tipo> getTodosTipos() throws DAOException {
        try {
            RowMapper<Tipo> mapper = getRowMapper();
            return getJdbcTemplate().query(this.sql03, mapper);
        } catch (EmptyResultDataAccessException ex) {
            throw new DAOException("Não há registros na tabela de tipos.");
        } catch (DataAccessException e) {
            throw new DAOException(e.getMessage());
        }

    }



    private RowMapper<Tipo> getRowMapper() {
        RowMapper<Tipo> mapper = new RowMapper<Tipo>() {
            public Tipo mapRow(ResultSet rs, int rowNum) throws SQLException {
                Tipo t = new Tipo();
                t.setTipoId(rs.getLong("tipo_id"));
                t.setDescricao(rs.getString("descricao"));

                return t;
            }
        };
        return mapper;

    }

    protected SimpleJdbcInsert getSji() {
        return sji;
    }

    protected void setSji(SimpleJdbcInsert sji) {
        this.sji = sji;
    }


}
form.xhtml:

<h:outputText value="TIPO:"/>
            <p:selectOneMenu value="#{publicacaoMB.publicacao.tipo}" converter="tipoConverter">
                <f:selectItems value="#{tipoMB.listTipos}" var="tipo"
                            itemLabel="#{tipo.descricao}" itemValue="#{tipo.tipoId}"/>
            </p:selectOneMenu>

看起来您的转换器逻辑有误

  • 在getAsObject中,返回的不是1个对象,而是整个数组。通过匹配一个
    tipo
    属性,您应该只返回一个。您可以使用tipoId,只要每个tipo实例都是唯一的。hashCode也可以做到这一点
  • 在getAsString中,应该返回在getAsObject中用于标识对象的相同属性。
    描述似乎不正确
  • 在selectOneMenu组件中,使用对象本身,而不是它的属性(
    itemValue=“#{tipo}”

  • 看起来你把转换器的逻辑搞错了

  • 在getAsObject中,返回的不是1个对象,而是整个数组。通过匹配一个
    tipo
    属性,您应该只返回一个。您可以使用tipoId,只要每个tipo实例都是唯一的。hashCode也可以做到这一点
  • 在getAsString中,应该返回在getAsObject中用于标识对象的相同属性。
    描述似乎不正确
  • 在selectOneMenu组件中,使用对象本身,而不是它的属性(
    itemValue=“#{tipo}”

  • 我认为这是一个错误。当itemLabel表达式解析为null(#{myObject.name}=>null)时,Primefaces显示对象的toString值。这是错误的,因为toString方法可能没有被重写,这将导致向最终用户呈现应用程序的内部(类名等)。这件事发生在我的一次演讲中,非常尴尬。由于数据库中的数据不正确,该值为null

    我猜PF实现者假设如果itemLabel为null,那是因为它没有被设置,并且意图确实是在整个对象上使用toString。但itemLabel可能已设置但已解析为null,在这种情况下,Primefaces应显示null值,即“null”、空字符串“!!”等


    selectItems标签可以有一个“null value”属性,告诉PF在itemLabel解析为null时显示什么。

    我认为这是一个Primefaces错误。当itemLabel表达式解析为null(#{myObject.name}=>null)时,Primefaces显示对象的toString值。这是错误的,因为toString方法可能没有被重写,这将导致向最终用户呈现应用程序的内部(类名等)。这件事发生在我的一次演讲中,非常尴尬。由于数据库中的数据不正确,该值为null

    我猜PF实现者假设如果itemLabel为null,那是因为它没有被设置,并且意图确实是在整个对象上使用toString。但itemLabel可能已设置但已解析为null,在这种情况下,Primefaces应显示null值,即“null”、空字符串“!!”等


    selectItems标记可以有一个“null值”属性,告诉PF在itemLabel解析为null时显示什么。

    转换器逻辑确实没有意义,但这仍然不能解释所描述的item label问题,因为它不涉及转换器。谢谢@yannicuLar,我更改了getAsObject和getAsString,但仍然显示toString()。但是当我使用时:
    code的selectItensTipos.add(new SelectItem(String.valueOf(t.getTipoId()),t.getdescripao());'代码
    有效,有什么想法吗?你能提供Tipo类的更多代码吗?我想检查类声明(注释、实现、扩展等)以及tipoId和descripao getter和setters@yannicuLar整个班级都是蒂波。@NatáliaBatuta抱歉,我没看到任何错误。您可以搜索已知的PF错误,并尝试更新版本。或者在Tipo.getDescriptaO()中使用断点进行调试转换器逻辑确实没有意义,但这仍然不能解释所描述的item label问题,因为它不涉及转换器。谢谢@yannicuLar,我更改了getAsObject和getAsString,但仍然显示toString()。但是当我使用时:
    code的selectItensTipos.add(new SelectItem(String.valueOf(t.getTipoId()),t.getdescripao());'代码
    有效,有什么想法吗?你能提供Tipo类的更多代码吗?我想检查类声明(注释、实现、扩展等)以及tipoId和descripao getter和setters@yannicuLar整个班级都是蒂波。@NatáliaBatuta抱歉,我没看到任何错误。您可以搜索已知的PF错误,并尝试更新版本。或者使用Tipo中的断点进行调试。getDescriptaO()是Tipo a
    ManagedBean
    ,实现了
    java.io.Serializable
    ?是Tipo a
    ManagedBean
    ,实现了
    java.io.Serializable
        @FacesConverter(value="tipoConverter")
    public class TipoConverter implements Converter {
    
        @EJB private Tipo tipo;
        @EJB private TipoFacade tipoFacade;
    
        @Override
        public Object getAsObject(FacesContext context, UIComponent component, String value)
                throws ConverterException {
            try {
                return tipoFacade.getTipoPorId(Long.parseLong(value));
            } catch (NumberFormatException e) {
                e.printStackTrace();
            } catch (DAOException e) {
                e.printStackTrace();
            }
            return value;
    
        }
    
        @Override
        public String getAsString(FacesContext context, UIComponent component,
                Object value) throws ConverterException {
            if (value == null) {
                return "";
            } 
            if (!(value instanceof Tipo)) {
                throw new ConverterException("Não é um tipo válido " + value );
            }
            return ((Tipo) value).getTipoId().toString();
    
        }
    
    <h:outputText value="TIPO:"/>
                <p:selectOneMenu value="#{publicacaoMB.publicacao.tipo}" converter="tipoConverter">
                    <f:selectItems value="#{tipoMB.listTipos}" var="tipo"
                                itemLabel="#{tipo.descricao}" itemValue="#{tipo.tipoId}"/>
                </p:selectOneMenu>