Solucionado (ver solução)
Solucionado
(ver solução)
9
respostas

Quando uso uma Lista aparece o erro java.lang.NumberFormatException: For input string: "cidade"

Boa noite a todos, porque quando estou usando uma lista? ele me retorna esse erro? ta tentando converter algo aqui? Onde o erro ocorre.

<h:form>
            <p:dataTable var="cliente" value="#{clienteController.clientes}" style="margin-bottom:40px">
                <f:facet name="header">
                    Tabela Clientes
                </f:facet>
            <p:column headerText="Cidade" >
                    <h:outputText value="#{cliente.enderecos.cidade}" />
                </p:column>
                <p:column headerText="Bairro" >
                    <h:outputText value="#{cliente.enderecos.bairro}" />
                </p:column>
                <p:column headerText="Numero Casa" >
                    <h:outputText value="#{cliente.enderecos.numeroCasa}" />
                </p:column>
        </p:dataTable>
    </h:form>

O meu enderecos é uma lista, porque esse erro? não entendi o porque dele

9 respostas

Boa noite, Alisson!

Imagino que o seu erro esteja acontecendo porque clienteController.clientes retorna uma lista de clientes e, quando você tenta chamar "cliente.endereços", que também é uma lista, você não especifica de qual elemento da lista de endereços você que sejam exibidos os atributos cidade, bairro e numeroCasa. Informar qual elemento da lista de endereços você quer que seja exibido, seria algo tipo (atente para os colchetes):

<h:outputText value="#{cliente.enderecos[0].cidade}" />
<h:outputText value="#{cliente.enderecos[0].bairro}" />
<h:outputText value="#{cliente.enderecos[0].numeroCasa}" />
...
depois
...
<h:outputText value="#{cliente.enderecos[1].cidade}" />
<h:outputText value="#{cliente.enderecos[1].bairro}" />
<h:outputText value="#{cliente.enderecos[1].numeroCasa}" />

Como toda lista, você precisaria iterar essa lista de endereços de cada cliente. Não sei se é possível, mas você poderia tentar criar um novo h:dataTable dentro do h:dataTable atual para fazer essa iteração, ou tentar um ui:repeat ou c:forEach, algo tipo:

<h:form>
    <p:dataTable var="cliente" value="#{clienteController.clientes}" style="margin-bottom:40px">
        <f:facet name="header">Tabela Clientes</f:facet>
        <p:column headerText="Nome do cliente >
            <h:outputText value="#{cliente.nome}" />
        </p:column>
        <p:column>
            <p:dataTable var="endereco" value="#{cliente.enderecos}">
                <f:facet name="header">Endereços do cliente</f:facet>
                <p:column headerText="Cidade" />
                    <h:outputText value="#{endereco.cidade}" />
                </p:column>
                <p:column>
                    <h:outputText value="#{endereco.bairro}" />
                 </p:column>
                 <p:column>
                     <h:outputText value="#{endereco.numeroCasa}" />
                </p:column>
             </p:dataTable>
        </p:column>
 </p:dataTable>
</h:form>

Particularmente, eu preferiria só exibir os endereços do cliente quando o usuário clicasse para exibir os dados desse cliente. Assim, seria apenas uma lista simples, como a que você apresentou, sem aninhamentos.

Não sei se o exemplo funciona na prática, mas como você queria entender a razão do erro, penso que fique mais claro a necessidade de especificar de qual elemento da lista de endereços do cliente queremos exibir a cidade, o bairro e o numeroCasa.

Qualquer dúvida, só postar! Abraço.

Ola Manoel obrigado pelas dicas e pela otima explicação, só me restou uma duvida, o meu Clientes nao seria uma lista, só seria uma lista o meu enderecos, toda vez que eu for adicionar um endereco tenho que especificar assim?

{cliente.enderecos[0].cidade}

Se quiser adicionar outra cidade para esse mesmo cliente só trocaria o 0 para 1?

Manoel deu certo a uma tabela dentro da outra, funcionou certinho, porem fico cortando tudo as palavras, da primeira maneira que você passo esta correto em programar assim? tipo cliente.enderecos[0].cidade esta certo assim? é uma boa pratica?

E aí, Alisson! Que bom que tá dando certo! Então... Você colocou #{clienteController.clientes}, daí achei que "clientes" fosse um List de Cliente (algo tipo: List). Você disse isso na questão:

"O meu enderecos é uma lista, porque esse erro? não entendi o porque dele"

Se #{clienteController.clientes} retorna apenas um cliente (que contem uma lista de endereços), você só precisa fazer o h:dataTable iterar nos endereços e não no cliente. Seria somente o h:dataTable interno.

<h:outputText value="#{clienteController.cliente.nome}" />
<p:dataTable var="endereco" value="#{clienteController.cliente.endereco">
    <f:facet name="header">Endereços do cliente</f:facet>
    <p:column headerText="Cidade" />
        <h:outputText value="#{endereco.cidade}" />
    </p:column>
    <p:column>
        <h:outputText value="#{endereco.bairro}" />
    </p:column>
    <p:column>
        <h:outputText value="#{endereco.numeroCasa}" />
    </p:column>
</p:dataTable>

A primeira forma que te mostrei, era só pra você entender que quando queremos exibir os atributos cidade, bairro e numeroCasa de cada um dos elementos da lista, precisamos dizer de qual elemento da lista queremos exibir, por isso você teria que iterar a lista pra alterar o índice ([0], depois [1], depois [2], etc). É uma péssima prática fazer isso! Só mostrei pra você entender que tinha que mostrar cidade, bairro e numeroCasa do elemento da posição [0] da lista, depois as informações do elemento da posiçao [1], etc. Por isso é melhor iterar com um dataTable mesmo (até porque se você colocou uma lista de endereços, pode ser que você não saiba quantos estarão cadastrados para cada cliente).

Sugiro que você dê nomes no singular para os atributos que não são lista e no plural para os que são. Como cliente não é uma lista, dê o nome só de cliente, assim, o get dele será getCliente(). No caso de endereco, como é uma lista, dê o nome "enderecos", assim, o get dele ficará getEnderecos(). Porque quando olhamos o nome do atributo, assumimos que ele é uma lista ou não pelo nome. Seu atributo "clientes" sugere que ele seja um list, assim como "enderecos".

Quanto aos cortes nas palavras, deve ser alguma limitação na largura da página ou do h:dataTable, delimitado pelo CSS ou HTML, que podem estar cortando as larguras tanto do h:dataTable interno (de endereços), quanto o externo (de clientes).

Qualquer dúvida, só postar! Abraço.

Manoel otimas dicas, muito obrigado!! Só me restou uma unica duvida.

<p:dataTable var="endereco" value="#{clienteController.cliente.endereco">
    <f:facet name="header">Endereços do cliente</f:facet>
    <p:column headerText="Cidade" />
        <h:outputText value="#{endereco.cidade}" />
    </p:column>
    <p:column>
        <h:outputText value="#{endereco.bairro}" />
    </p:column>
    <p:column>
        <h:outputText value="#{endereco.numeroCasa}" />
    </p:column>
</p:dataTable>

Na opção que você me passou eu estou iterado a minha lista com uma tabela correto? mas aqui vem minha duvida, e os dados do cliente como o nome sobrenome etc... como fazer isso? do jeito que você me falo daria certo uma tabela dentro da outra correto? é oque vocês programadores fazem quando usam tabela?

solução!

"Vocês programadores?" kkk. "Nós", Alisson, afinal, você também é um. hehe.

Há várias formas de fazer. Você pode exibir os dados fora do h:dataTable, pode exibir os dados em um h:dataTable aninhado (que é o exemplo que você estava tendo problemas), pode usar os ui:repeat, os c:forEach, etc.

Se você precisa exibir os dados de um cliente de forma tabulada, tipo:

Nome        Endereço        Telefone                Ações
José        Rua Jota        (99) 3309-1234        editar | remover
Ana         Rua Xis         (89) 3382-5436        editar | remover

Você pode iterar a lista de clientes com um h:dataTable mesmo. Se precisar exibir uma lista de qualquer coisa de cada um dos clientes, como se, por exemplo, um cliente tivesse vários filhos (List, você poderia fazer a subtabela que falamos). Se for só exibir os dados da forma tabulada como mostrei acima, pode ser só um h:dataTable simples mesmo.

Aqui um exemplo do que fazemos aqui no trampo:

<h:dataTable value="#{AtoMB.buscarTodos()}" var="ato">
    <h:column>
        <f:facet name="header">Tabela</f:facet>
        <h:outputText value="#{ato.tabela.descricao}" />
    </h:column>
    <h:column>
        <f:facet name="header">Descrição</f:facet>
        <h:outputText value="#{ato.descricao}" />
    </h:column>
    <h:column>
        <f:facet name="header">Ações</f:facet>
        <h:commandLink title="Editar">
            <f:setPropertyActionListener value="#{ato}" target="#{atoMB.ato}"/>
            <f:ajax execute="@form" render="@form :frmCadastrarAto"/>
        </h:commandLink>
        <h:commandButton title="Remover" value="Remover" action="#{atoMB.remover()}">
            <f:setPropertyActionListener target="#{atoMB.tabelaAto}" value="#{ato}" />
            <f:ajax render="@form :frmCadastrarAto"/>
        </h:commandButton>
    </h:column>
</h:dataTable>

Abraço.

Muito obrigado pelas dicas cara, kkkkkkk to entrando nesse mundo de programação kkkk. Um dia chego ao nivel de lógica de programação kk. Abraço man

O caminho é esse mesmo! Se deu certo, você pode marcar o tópico como resolvido, pra ele sair lá da lista de tópicos com soluções pendentes.

Abraço, brother!

Correto obrigado mais uma vez abraço irmão