JSF + Sessão = NULLPointerException

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

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

[quote=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[/quote]

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

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

Ricardo

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.

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.

[quote=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.[/quote]

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

[quote=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.[/quote]

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

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.

[quote=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.[/quote]

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

Ricardo

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

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

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

Ricardo

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

Perfeito !!!
Muito Obrigado.

Ricardo