JSF + Sessão = NULLPointerException

14 respostas
ricardo13

olá pessoal,

Estou fazendo um exemplo de Login/Senha sendo que, quando o usuário loga no sistema o objeto USUARIO (uma entidade) é inserido na sessão.

Por exemplo,

Se o usuário logar, ele será redirecionado para outra página (“editUser.xhtml”). O Managed-bean responsável por essa página (“editUser.xhtml”) vai pegar o objeto na sessão e instanciar as informações contidas na página com os dados do objeto.

Eu estou acessando o objeto na sessão da seguinte forma.

HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
Usurio u = (Usuario) session.getAttribute("USUARIO");

Quando vou fazer deploy, o Tomcat mostra um NULLException. Se por acaso eu comentar essas duas linhas, o sistema é implantado normalmente.
Lembrando que esse trecho de código acima foi colocado no construtor do MB.

Bom, alguém sabe me dizer oq ta acontecendo ???

Ricardo

14 Respostas

C

E você está fazendo assim para colocar o usuario na sessão?

FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("USUARIO", objUsuario);

E para buscar o usuario setado não seria?

FacesContext context = FacesContext.getCurrentInstance();
        ExternalContext extContext = context.getExternalContext();
        Usuario user = (Usuario) extContext.getSessionMap().get("USUARIO");

tenta isso e ve se rola

[]s

ricardo13

cleberson.henrique:
E você está fazendo assim para colocar o usuario na sessão?

FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("USUARIO", objUsuario);

E para buscar o usuario setado não seria?

FacesContext context = FacesContext.getCurrentInstance();
        ExternalContext extContext = context.getExternalContext();
        Usuario user = (Usuario) extContext.getSessionMap().get("USUARIO");

tenta isso e ve se rola

[]s

Não Rolou. Continuou o mesmo Problema.
Eu acho que o FacesContext não está instanciado ou a sessão não está sendo instanciada.

Bom, para setar eu estava fazendo isso:

usuario = usuarioComponent.obterUsuarioPorIDLoginSenha(loginSenhaObtido);
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
session.setAttribute("USUARIO", usuario);

E para pegar o objeto, eu estou fazendo o seguinte trecho:

HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
Usuario u = (Usuario) session.getAttribute("USUARIO");
this.setUsuario(u);

Ricardo

ricardo13

Existe a possibilidade deste erro está acontecendo por estar no construtor de Managed-bean ??

Ricardo

dev.rafael

Pq vc ñ tenta assim:

@ManagedBean
@SessionScoped
public class UserSession implements Serializable {

  private User user;

  public User getUser() { return user; }

  public String login() { ... }
  public String logout() { ... }

}
@ManagedBean
@RequestScoped
public class AnotherBeanThatNeedsUser {

  @ManagedProperty(value = "#{userSession.user})
  private User user;

  public User getUser() { return user; }
  public void setUser(User user) { this.user = user; }

}

Ñ user a sessão da Servlet p/ armazenar coisas, crie ManagedBeans em escopo de sessão p/ isso.

kicolobo

Opa.

Observa esta linha do seu código:

HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);

Quando você passa o parâmetro false, você está dizendo ao container para que não crie uma nova sessão caso esta não exista. Mude o parâmetro para true, que o container criará automáticamente a sessão e, provavelmente, o problema irá parar.

ricardo13

dev.rafael:
Pq vc ñ tenta assim:

@ManagedBean
@SessionScoped
public class UserSession implements Serializable {

  private User user;

  public User getUser() { return user; }

  public String login() { ... }
  public String logout() { ... }

}
@ManagedBean
@RequestScoped
public class AnotherBeanThatNeedsUser {

  @ManagedProperty(value = "#{userSession.user})
  private User user;

  public User getUser() { return user; }
  public void setUser(User user) { this.user = user; }

}

Ñ user a sessão da Servlet p/ armazenar coisas, crie ManagedBeans em escopo de sessão p/ isso.

Bom, outra coisa que eu eskeci de mencionar (não sei se é relevante) é que estou usando SPRING 2.5
Não estou usando as annotations do JSF (@ManagedBean, @RequestScoped, …)

Meu código está mais ou menos assim

@Component("verificaLoginSenhaMB")
public class VerificaLoginSenha implements Serializable {

  private User user;
  private UserService userService;

  public User getUser() { return user; }

  public String login() { 

       if(usuario_existe)
         //adiciona a variável user na sessão e redireciona (navigation-rule) para outra página
  }

  public String logout() { ... }
@Component("usuarioHomePageMB")
public class UsuarioHomePage implements Serializable {

    private User user;

    public UsuarioHomePage() {
      // Pega o user da sessão e atribui a variável user deste MB
      HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);  
      Usuario u = (Usuario) session.getAttribute("USUARIO");      
    }
}

Ricardo

ricardo13

kicolobo:
Opa.

Observa esta linha do seu código:

HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);

Quando você passa o parâmetro false, você está dizendo ao container para que não crie uma nova sessão caso esta não exista. Mude o parâmetro para true, que o container criará automáticamente a sessão e, provavelmente, o problema irá parar.

Tentei todas as combinações possíveis entre TRUE e FALSE tanto no set quanto get da sessão (medida de desespero, rs) e nada.
O NULLException permaneceu.

Ricardo

dev.rafael

Eu nunca mexi com Spring mas, ele ñ permite q vc especifique outros escopos p/ os seus ManagedBeans?

PS.: vc ñ deveria usar verbos como nomes de classes.

ricardo13

dev.rafael:
Eu nunca mexi com Spring mas, ele ñ permite q vc especifique outros escopos p/ os seus ManagedBeans?

PS.: vc ñ deveria usar verbos como nomes de classes.

Vou ver e também vou alterar os nomes dos MBs.

Ricardo

ricardo13

olá pessoal,

Depois de mexer bastante eu consegui fazer funcionar.
Mas eu acredito que dessa forma que está funcionando não está correta.

Eu consegui recuperar o objeto da sessão utilizando o FacesContext, mas somente se, o MB estiver com o escopo de sessão (session).

É verdade isso ??
Eu não vi nos artigos falando nada sobre isso.

Ricardo

dev.rafael

Ñ use HttpSession. O JSF oferece uma ótima abstração da camada WEB. Sempre q vc quiser dados no escopo de sessão use ManagedBean no escopo de sessão. Vc sempre pode usar ManagedProperties p/ obter esse ManagedBeans apartir de outros ManagedBeans.

ricardo13

A annotation @ManagedProperty está disponível para a versão 1.2 ??

Ricardo

dev.rafael

Ñ. Na versão 1.2 vc precisa usar o faces-config.xml p/ configurar ManagedProperties:

<managed-bean>
  <managed-bean-name>userSession</managed-bean-name>
  <managed-bean-class>myprj.UserSession</managed-bean-class>
  <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<managed-bean>
  <managed-bean-name>myBean</managed-bean-name>
  <managed-bean-class>myprj.MyBean</managed-bean-class>
  <managed-bean-scope>request</managed-bean-scope>
  <managed-property>
    <property-name>user</property-name>
    <value>#{userSession.user}</value>
  </managed-property>
</managed-bean>
public class UserSession implements Serializable {  
  
  private User user;  
  
  public User getUser() { return user; }  
  
  public String login() { ... }  
  public String logout() { ... }  
  
}
public class AnotherBeanThatNeedsUser {  
  
  private User user;  
  
  public User getUser() { return user; }  
  public void setUser(User user) { this.user = user; }  
  
}
ricardo13

Perfeito !!!
Muito Obrigado.

Ricardo

Criado 8 de novembro de 2010
Ultima resposta 8 de nov. de 2010
Respostas 14
Participantes 4