JSF验证错误h:selectOneMenu但仅适用于一个项目

时间:2013-04-26 15:43:25

标签: java jsf primefaces glassfish-3 selectonemenu

我看到有一百万个主题在谈论这个问题,但没有一个与我的问题相符,而且这里是:

我的查询将以下结果列入清单:

  
      
  1. Caixa Economica Federal
  2.   
  3. ASSOCIAÇÃODOSFRANQUEADOS DA REDE DE LANCHOLETES GIRAFFAS
  4.   

尝试按h:selectOneMenu中的第一项搜索时,一切正常。但是当我尝试按列表中的第二项搜索时,我收到以下错误:

  

j_idt49:advertiserName:验证错误:值无效

这真的很奇怪,至少在我看来,我看到的所有先前的答案都没有任何意义,如果你考虑到某些值,搜索工作正常。

以下是我的代码:

commercialRecognized.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://java.sun.com/jsp/jstl/core">
    <h:body>
        <ui:composition template="jsf/template/template.xhtml">
            <ui:define name="conteudo">
                <h:outputScript target="body" library="js" name="commercialRecognized.js"/>
                <div id="wrapper">
                    <div id="body_site">
                        <div id="content">
                            <div class="success urlpie hide">#{bundle.OperacaoSucesso}</div>
                            <div class="error"></div>
                            <span class="clearfix_2">&nbsp;</span>
                            <h2><h:outputText value="#{bundle.ComerciaisReconhecidos}"></h:outputText></h2>
                            <p class="subtitle"><h:outputText value="#{bundle.ConsulteOsComerciais}"></h:outputText></p>
                            <div class="box">
                                <p class="w_100 txt_bold al_left"><h:outputText value="#{bundle.PesquisarPor}"></h:outputText>
                                </p>
                                <h:form><p:growl id="messages" showDetail="true"/></h:form>
                                <h:form>
                                    <ul class="form_list_left al_right w_800">
                                        <li>
                                            <h:outputLabel for="advertiserName" value="#{bundle.Anunciante_Title}"/>
                                            <h:selectOneMenu value="#{matchesController.selected.advertiserName}" id="advertiserName" class="w_220" title="#{bundle.Anunciante_Title}">
                                                <f:selectItem itemLabel="Selecione..." itemValue=""/>
                                                <f:selectItems value="#{matchesController.advertiserNames}"/>
                                            </h:selectOneMenu>
                                        </li>
                                        <li>
                                            <h:outputLabel for="agencyName" value="#{bundle.Agencia_Title}"/>
                                            <h:selectOneMenu value="#{matchesController.selected.agencyName}" id="agencyName" class="w_220" title="#{bundle.Agencia_Title}">
                                                <f:selectItem itemLabel="Selecione..." itemValue=""/>
                                                <f:selectItems value="#{matchesController.agencyNames}"/>
                                            </h:selectOneMenu>
                                        </li>
                                        <li>
                                            <h:outputLabel for="productName" value="#{bundle.Produto_Title}"/>
                                            <h:selectOneMenu value="#{matchesController.selected.productName}" id="productName" class="w_220" title="#{bundle.Produto_Title}">
                                                <f:selectItem itemLabel="Selecione..." itemValue=""/>
                                                <f:selectItems value="#{matchesController.productNames}"/>
                                            </h:selectOneMenu>
                                        </li>
                                        <li>
                                            <h:outputLabel for="iniDate" value="#{bundle.DataInicial_Title}"/>
                                            <h:inputText value="#{matchesController.selected.iniDate}" class="w_80 data" id="iniDate" required="false" validatorMessage="#{bundle.DataInicial_Title} inválida."/>
                                        </li>
                                        <li>
                                            <h:outputLabel for="finalDate" value="#{bundle.DataFinal_Title}"/>
                                            <h:inputText value="#{matchesController.selected.finalDate}" class="w_80 data" id="finalDate" required="false" validatorMessage="#{bundle.DataFinal_Title} inválida."/>
                                        </li>
                                        <li>
                                            <h:outputLabel for="iniTime" value="#{bundle.HoraInicial_Title}"/>
                                            <h:inputText value="#{matchesController.selected.iniTime}" class="w_80 hora" id="iniTime" required="false" validatorMessage="#{bundle.HoraInicial_Title} inválida."/>
                                        </li>
                                        <li>
                                            <h:outputLabel for="finalTime" value="#{bundle.HoraFinal_Title}"/>
                                            <h:inputText value="#{matchesController.selected.finalTime}" class="w_80 hora" id="finalTime" required="false" validatorMessage="#{bundle.HoraFinal_Title} inválida."/>
                                        </li>
                                        <li>
                                            <h:outputLabel for="equipmentName" value="#{bundle.NomeEquipamento_Title}"/>
                                            <h:inputText value="#{matchesController.selected.equipmentName}" class="w_130 equipment" id="equipmentName" required="false" validatorMessage="#{bundle.NomeEquipamento_Title} inválido."/>
                                        </li>
                                        <li>
                                            <h:outputLabel for="channelCode" value="#{bundle.CodigoCanal_Title}"/>
                                            <h:inputText value="#{matchesController.selected.channelCode}" class="w_80 channelCode" id="channelCode" required="false" validatorMessage="#{bundle.CodigoCanal_Title} inválido."/>
                                        </li>
                                        <li><h:commandLink action="#{matchesController.clear}" class="bt_limpar button29" style="margin-top:13px;"><span class="screen_reader_text">Limpar</span></h:commandLink></li>
                                        <li><h:commandLink action="#{matchesController.search}" class="bt_pesquisar button29" style="margin-top:13px;"><span class="screen_reader_text">Pesquisar</span></h:commandLink></li>
                                    </ul>
                                </h:form>

                                <span class="clearfix_2">&nbsp;</span>
                            </div>
                            <div class="resultado">
                                <c:if test="#{matchesController.tableRs.size() > 0}">
                                    <h:dataTable id="tableResultados" value="#{matchesController.tableRs}" var="item">
                                        <h:column>
                                            <f:facet name="header">
                                                <h:outputText value="#{bundle.DuracaoComercialCadastrado}"/>
                                            </f:facet>
                                            <h:outputText value="#{item.durationCommercialRegistered}"/>
                                        </h:column>
                                        <h:column>
                                            <f:facet name="header">
                                                <h:outputText value="#{bundle.DuracaoComercialReconhecido}"/>
                                            </f:facet>
                                            <h:outputText value="#{item.durationCommercialRecognized}"/>
                                        </h:column>
                                        <h:column>
                                            <f:facet name="header">
                                                <h:outputText value="#{bundle.Versao}"/>
                                            </f:facet>
                                            <h:outputText value="#{item.version}"/>
                                        </h:column>
                                        <h:column>
                                            <f:facet name="header">
                                                <h:outputText value="#{bundle.ID}"/>
                                            </f:facet>
                                            <h:outputText value="#{item.ID}"/>
                                        </h:column>
                                        <h:column>
                                            <f:facet name="header">
                                                <h:outputText value="#{bundle.Confiabilidade}"/>
                                            </f:facet>
                                            <h:outputText value="#{item.confiability}"/>
                                        </h:column>
                                        <h:column>
                                            <f:facet name="header">
                                                <h:outputText value="#{bundle.Distorcao}"/>
                                            </f:facet>
                                            <h:outputText value="#{item.distortion}"/>
                                        </h:column>
                                        <h:column>
                                            <f:facet name="header">
                                                <h:outputText value="#{bundle.DataEHoraExibicao}"/>
                                            </f:facet>
                                            <h:outputText value="#{item.dateShow}"/>&nbsp;
                                            <h:outputText value="#{item.timeShow}"/>
                                        </h:column>
                                        <h:column>
                                            <f:facet name="header">
                                                <h:outputText value="#{bundle.SegundosDoComercial}"/>
                                            </f:facet>
                                            <h:outputText value="#{item.commercialSeconds}"/>
                                        </h:column>
                                        <h:column>
                                            <f:facet name="header">
                                                <h:outputText value="#{bundle.Status}"/>
                                            </f:facet>
                                            <h:outputText value="#{item.status}"/>
                                        </h:column>
                                        <h:column>
                                            <f:facet name="header">
                                                <h:outputText value="#{bundle.TituloMaterial}"/>
                                            </f:facet>
                                            <h:outputText value="#{item.materialTitle}"/>
                                        </h:column>
                                        <h:column>
                                            <f:facet name="header">
                                                <h:outputText value="#{bundle.AnuncianteTable}"/>
                                            </f:facet>
                                            <h:outputText value="#{item.announcer}"/>
                                        </h:column>
                                    </h:dataTable>
                                </c:if>
                            </div>
                            <span class="clearfix_2">&nbsp;</span>
                        </div>
                        <!--#content--> 
                    </div>
                    <!--#body_site--> 
                </div>
                <!--#wrapper-->
            </ui:define>
        </ui:composition>
    </h:body>
</html>

MatchesController.java

package net.checkmidia.auditoria.managedbean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import net.checkmidia.auditoria.entity.Matches;
import net.checkmidia.auditoria.managedbean.converter.SearchCommercialsDTO;
import net.checkmidia.auditoria.managedbean.converter.TableResultSearchCommercialsDTO;
import net.checkmidia.auditoria.managedbean.helper.JsfHelper;
import net.checkmidia.auditoria.session.MatchesSession;
import net.checkmidia.auditoria.util.DateTimeUtil;
import net.checkmidia.auditoria.util.ObjectUtil;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;

@ManagedBean(name = "matchesController")
@SessionScoped
public class MatchesController implements Serializable {

    /* Instância de SearchCommercialsDTO com todos os dados digitados na pesquisa */
    private SearchCommercialsDTO current;

    /* Lista com todos os resultados obtidos na query de pesquisa */
    private List<TableResultSearchCommercialsDTO> tableRs = new ArrayList<TableResultSearchCommercialsDTO>();

    @EJB
    private MatchesSession ejbFacade;

    private int selectedItemIndex;

    /**
     * Combos
     */
    private String advertiserName;
    private String agencyName;
    private String productName;
    private Map<String, String> advertiserNames = new HashMap<String, String>();
    private Map<String, String> agencyNames = new HashMap<String, String>();
    private Map<String, String> productNames = new HashMap<String, String>();

    /**
     * Construtor default
     */
    public MatchesController() {}

    /**
     * Obtém todos os inputs marcados com "selected"
     * @return o formulario de pesquisa
     */
    public SearchCommercialsDTO getSelected() {
        if (current == null) {
            current = new SearchCommercialsDTO();
            selectedItemIndex = -1;
        }
        return current;
    }

    /**
     * Obtém a facade
     * @return facade
     */
    public MatchesSession getFacade() {
        return ejbFacade;
    }

    /**
     *  Popula o combo de anunciantes com todos os anunciantes gravados no banco
     */
    public void getAdvertisers() {
        try {
            List<String> advertiserList = ejbFacade.getAdvertiser();
            for (String advertiser : advertiserList) {
                advertiserNames.put(advertiser, advertiser);
            }
        } catch (Exception ex) {
            Logger.getLogger(MatchesController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     *  Popula o combo de agências com todos os agências gravados no banco
     */
    public void getAgencys() {
        try {
            List<String> agencyList = ejbFacade.getAgencys();
            for (String agency : agencyList) {
                agencyNames.put(agency, agency);
            }
        } catch (Exception ex) {
            Logger.getLogger(MatchesController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     *   Popula o combo de produtos com todos os produtos gravados no banco
     */
    public void getProducts() {
        try {
            List<String> productList = ejbFacade.getProducts();
            for (String product : productList) {
                productNames.put(product, product);
            }
        } catch (Exception ex) {
            Logger.getLogger(MatchesController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Inicializa os métodos para popular os combos assim que a página
     * for carregada
     */
    @PostConstruct
    public void combo(){
        getAdvertisers();
        getAgencys();
        getProducts();
    }

    /**
     * Limpa todos os dados do formulário de pesquisa e da tabela
     */
    public void clear() {
        tableRs.clear();
    }

    /**
     * Método de pesquisa
     * Esse método executa a facade e então obtém os resultados da pesquisa de acordo
     * com o formulario de pesquisa populando, então, a tabela
     * @return null
     */
    public String search() {
        try {
            List<Matches> execute = getFacade().searchMatches(current);
            if (!ObjectUtil.isEmpty(execute)) {
                tableRs.clear();
                for (int i = 0; i < execute.size(); i++) {
                    tableRs.add(
                            new TableResultSearchCommercialsDTO(
                            String.valueOf(execute.get(i).getMatchSearchedMaterialStartPosition()),
                            String.valueOf(execute.get(i).getMatchSourceMaterialStartPosition()),
                            String.valueOf(execute.get(i).getEngineVersion()),
                            String.valueOf(execute.get(i).getId()),
                            String.valueOf(execute.get(i).getMatchDistortion()),
                            String.valueOf(execute.get(i).getMatchMethod()),
                            DateTimeUtil.getDate(execute.get(i).getStartDate()),
                            DateTimeUtil.getTime(execute.get(i).getStartDate()),
                            String.valueOf(execute.get(i).getDuration()),
                            String.valueOf(execute.get(i).getStatus()),
                            String.valueOf(execute.get(i).getIdSourceMaterial().getTitle()),
                            String.valueOf(execute.get(i).getIdSourceMaterial().getAdvertiserName()),
                            String.valueOf(execute.get(i).getMatchConfidence())));
                }
                JsfHelper.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("SearchSuccessfull"));
            } else {
                tableRs.clear();
                JsfHelper.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("NoResults"));
            }
            return null;
        } catch (Exception e) {
            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, e);
            JsfHelper.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }

    /**
     * Getters e setters
     */
    public List<TableResultSearchCommercialsDTO> getTableRs() {
        return tableRs;
    }

    public String getAdvertiserName() {
        return advertiserName;
    }

    public void setCity(String advertiserName) {
        this.advertiserName = advertiserName;
    }

    public Map<String, String> getAdvertiserNames() {
        return advertiserNames;
    }

    public String getAgencyName() {
        return agencyName;
    }

    public String getProductName() {
        return productName;
    }

    public Map<String, String> getAgencyNames() {
        return agencyNames;
    }

    public Map<String, String> getProductNames() {
        return productNames;
    }

    public void setAdvertiserName(String advertiserName) {
        this.advertiserName = advertiserName;
    }

    public void setAgencyName(String agencyName) {
        this.agencyName = agencyName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public void setAdvertiserNames(Map<String, String> advertiserNames) {
        this.advertiserNames = advertiserNames;
    }

    public void setAgencyNames(Map<String, String> agencyNames) {
        this.agencyNames = agencyNames;
    }

    public void setProductNames(Map<String, String> productNames) {
        this.productNames = productNames;
    }

    public void setCities(Map<String, String> advertiserNames) {
        this.advertiserNames = advertiserNames;
    }

    public void setTableRs(List<TableResultSearchCommercialsDTO> tableRs) {
        this.tableRs = tableRs;
    }

}

MatchesControllerConverter.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.checkmidia.auditoria.managedbean.converter;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import net.checkmidia.auditoria.entity.Matches;
import net.checkmidia.auditoria.managedbean.MatchesController;

/**
 * Conversor para a entidade Matches
 * @author gabrielbombardi
 */
@FacesConverter(forClass = Matches.class)
public class MatchesControllerConverter implements Converter {

    public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
        if (value == null || value.length() == 0) {
            return null;
        }
        MatchesController controller = (MatchesController) facesContext.getApplication().getELResolver().
                getValue(facesContext.getELContext(), null, "matchesController");
        return value;
    }

    java.lang.Integer getKey(String value) {
        java.lang.Integer key;
        key = Integer.valueOf(value);
        return key;
    }

    String getStringKey(java.lang.Integer value) {
        StringBuffer sb = new StringBuffer();
        sb.append(value);
        return sb.toString();
    }

    public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
        if (object == null) {
            return null;
        }
        if (object instanceof Matches) {
            Matches o = (Matches) object;
            return getStringKey(o.getId());
        } else {
            throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + Matches.class.getName());
        }
    }
}
你能帮助我吗?谢谢!

PS: sorry for my poor english :)

1 个答案:

答案 0 :(得分:4)

您忘记根据the contractequals()班级中实施hashCode()Matches。 JSF正在使用它来匹配所选项目和可用项目。否则,只有new运算符创建的项目才会被视为与其自身相等,但new运算符创建的两个单独的实例永远不会被视为相等,即使它们在技术上可能基于其内部相等属性。

如果您的Matches类的id字段代表技术数据库标识符,那么应该这样做:

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

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

另见:


此外,转换器的getAsObject()方法看起来当前形式可疑。它完全忽略controller并直接返回原始未转换value。该方法应该将获得的表示Matches实例的ID的字符串转换为具体的Matches实例。

它应该看起来像这样:

public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
    if (value == null || value.length() == 0) {
        return null;
    }

    Integer id = getKey(value);
    Matches matches = getItSomehowBasedOn(id);
    return matches;
}