JSF + Sessão = NULLPointerException

14 respostas
R

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

R

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

R

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

Ricardo

D

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.

K

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.

R

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

R

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

D

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.

R

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

R

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

D

Ñ 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.

R

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

Ricardo

D

Ñ. 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; }  
  
}
R

Perfeito !!!
Muito Obrigado.

Ricardo

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