JSF commandButton acionando AJAX antes de clique

Olá a todos! Estou comecando com JSF hoje e estou tendo um probleminha que deve ser moleza para os experientes.
Estou utilizando o NetBeans 7 com Apache Tomcat 7 e JSF 2.0

Eu tenho um ManagedBean usuario, que possui um metodo public String getSaudacao() que deve ser chamado por um commandButton,
e retornar o nome do usuario.

@ManagedBean(name = "usuario")
@SessionScoped
public class UsuarioBean implements Serializable {

    private String nome;
    private String senha;

//getters e setters

    public String getSaudacao() {
        if (nome.length() == 0) {
            return "";
        } else {
            return "Bem vindo " + nome + " !";
        }
    }
}

O arquivo index.xhtml está da seguinte forma:

<?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:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>Login</title>
    </h:head>
    <h:body>
        <h1>Login</h1><br/>

        <!-- A propriedade prependID faz com que o id do form seja anexado
        aos id`s dos componentes nesse form. Exemplo: se o id do form é "form"
        um elemento text com id "texto" é acessado por form.texto-->
        <h:form prependId="false">
            <h3>Por favor digite o nome e senha.</h3><br/>
            <table>
                <tr>
                    <td>Usuário</td>
                    <td><h:inputText id="nome" value="#{usuario.nome}"></h:inputText></td>
                </tr>
                <tr>
                    <td>Senha</td>
                    <td><h:inputSecret id="senha" value="#{usuario.senha}"></h:inputSecret></td>
                </tr>
            </table>
            <p>
                <h:commandButton value="Login">
                    <f:ajax render="out" execute="nome senha"/>
                </h:commandButton>
            </p>
            <h3><h:outputText id="out" value="#{usuario.saudacao}"/></h3>
        </h:form>
    </h:body>
</html>

O problema que ocorre é uma NullPointerException que é gerada porque o usuario.nome esta null.
Porque o nome esta como null e não como String vazia “” ?
Ou seja o <h:outputText id="out" value="#{usuario.saudacao}"/> é executado antes mesmo do botão ser clicado.
E os dados de usuario ainda nao foram instanciados com nenhum valor. O que eu não estou vendo aqui ?

A solução que encontrei foi inicializar a variavel String nome = “”; Mas cá entre nós isso é gambiarra ! Não vou fazer isso no projeto inteiro ne ?
Quero saber porque este codigo é executado antes de ser chamado. Ja tente executar o projeto no GlassFish e o mesmo ocorreu.
Obrigado aos que lerem isto, e agradeço aos que me ajudarem !

Tenta colocar, no f:ajax event=“click”

Ocorreu o mesmo erro.

java.lang.NullPointerException at com.login.UsuarioBean.getSaudacao(UsuarioBean.java:45)

É a linha onde ele tenta acessar nome.lenght(),
Só que neste momento nome = null.

O que me parece estranho é que quando o objeto UsuarioBean é construído as suas variáveis de instancia String (nome e senha) não são setadas pela página com os valores “” dos campos <h:inputText> e <h:inputSecret>.

Descobri a fonte do erro ! E é bem inacreditável.
O problema está na ordem dos parâmetros em

<h:inputText id="nome" value="#{usuario.nome}"></h:inputText>

O atributo value não pode vir depois do atributo id !

<h:inputText value="#{usuario.nome}" id="nome"></h:inputText>

Assim funciona !
Tópico resolvido !

Me enganei, a solução não é essa.
O servidor não tinha atualizado a mudança que fiz, emfim, problema não resolvido.

[quote=kirill]Descobri a fonte do erro ! E é bem inacreditável.
O problema está na ordem dos parâmetros em

<h:inputText id="nome" value="#{usuario.nome}"></h:inputText>

O atributo value não pode vir depois do atributo id !

<h:inputText value="#{usuario.nome}" id="nome"></h:inputText>

Assim funciona !
Tópico resolvido ![/quote]

^ Isso não tem lógica!

Já experimentou criar: private String saudacao; ?

E além disso o erro pode nem ser na apresentação.
Pode ser lá no seu MB, mais exatamente aqui:

==> (nome.length() == 0)

Pois é encontrado um null e dai surge o nullpointer.
Como teste, tente assim:

public String getSaudacao() {
if (nome == null) {
return “(Vazio)”;
} else {
return “Bem vindo " + nome + " !”;
}
}

Eu vi que no código que você postou a um comentário de getters e setters.

Obrigatoriamente deve ter o getter e setter dos dois atributos: nome e senha.

@ManagedBean(name = "usuario")   
@SessionScoped   
public class UsuarioBean implements Serializable {   
  
    private String nome;   
    private String senha;   
  
//getters e setters   
   public void setNome(String nome){
       this.nome = nome;
}

  public String getNome(){
       return nome;
}
   public void setSenha(String senha){
       this.senha = senha;
}

  public String getSenha(){
       return senha;
}  
    public String getSaudacao() {   
        if (nome.length() == 0) {   
            return "";   
        } else {   
            return "Bem vindo " + nome + " !";   
        }   
    }   
}  

Falou!!!

Valeu pelo feedback pessoal !
Realmente só existem duas maneiras de resolver o problema.

Uma é inicializando a variável nome

private String nome = "";

A outra é tratar a NullPointerException no método getSaudacao

int len = 0; try{ len = nome.length(); }catch(NullPointerException e){ return ""; } if (len == 0) { return ""; } else { return "Bem vindo " + nome + " !"; }