Keep a session in Java with jsf and ManagedBean

1

Starting with Java EE and JSF, I need to create a simple login and keep the id and nick of the user in the session.

For that, create a class

package Controlador;

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class SessionBean implements Serializable {

/**
 * 
 */
private static final long serialVersionUID = 1;

private int usuarioId;

private String usuarioNick;



public SessionBean() {
    super();
}...

From another class I try to save data in it, but when I try to access it returns Null pointer exception .

@ManagedBean
[email protected]
public class UsuarioSessionBean {

@EJB
private UsuarioSessionDAO usuarioSession;

@ManagedProperty("#{sessionBean}")
private SessionBean sessionBean;

public void setSessionBean(SessionBean sb){
    if(sb != null){
        this.sessionBean = sb;
    }
}   
...

public String Login(){

    Usuario usr = usuarioSession.Login(usuario.getNick(),   usuario.getPass());
    if(usr != null){
        sessionBean.setUsuarioId(usr.getId());
        sessionBean.setUsuarioNick(usr.getNick());
        return "loginOk";
    }
    return "loginNo";
}

What am I doing wrong? Or rather, what would be the way to create a simple login?

    
asked by Maske 06.05.2016 в 23:13
source

2 answers

1
  • It is much more recommended to use beans managed by CDI than by JSF. Now, the use of @ManagedBean is not advised. Your replacement is @Named which indicates that it is a CDI bean . It is important to not mix ManagedBeans with CDI scopes because it simply will not work and you will have problems at runtime.

    import javax.inject.Named;
    import javax.enterprise.context.SessionScoped; // importante
    @Named
    @SessionScope
    public class SessionBean implements Serializable { ... }
    
  • Any class that will be passivated (serialized and saved on the hard drive), as in the case of backing beans that have scopes ViewScoped, SessionScoped, FlowScoped, ConversationScoped, ApplicationScoped must be serializable because CDI They are serialized. Your class UsuarioSessionBean is not serializable.

    @Named
    @SessionScoped
    public class UsuarioSessionBean implements Serializable { ... }
    
  • Choose the scope (scope, scope) of your backing beans correctly. If you have many beans in session the application will lose performance, because in each response you send all those beans.

  • For example, you can create a utility class that allows you to obtain and add values to the session.

    public class SessionUtils implements Serializable {
    
        public void add(String key, Object value) {
            FacesContext.getCurrentInstance().getSessionMap().put(key, value);
        }
    
        public void get(String key) {
            FacesContext.getCurrentInstance().getSessionMap().get(key);
        }
    }
    

    And you do not need UsuarioSessionBean , just a login controller that injects SessionUtils .

    @Named
    @RequestScoped
    public class LoginBean {
    
       @Inject // inyectamos la dependencia
       private SessionUtils session;
       private String username;
       private String password;
    
       public String login() {
          // comprobar credenciales
          if(exito) {
              // añades el usuario a sesión
              sessionUtils.add("usuarioLogueado", usuario);
              return "home";
          }
          FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Acceso denegado", "Usuario o contraseña incorrecta");
          // como mensaje global
          FacesContext.getCurrentInstance().addMessage(null, message);
          return null; // retorna al mismo login
       }
    
       // getters y setters
    }
    

    UPDATE

    In the StackExchange Android app I was shown as "active", now I've seen the date and it's May . Excuse me for the mess.

        
    answered by 13.06.2016 / 16:08
    source
    1

    I have made a login with the Google API Oauth2 is the same thing you want to do but instead of passing a Session variable, you will have to pass two variables " login " and " password "

    login.xhtml

            <h:commandLink action="#{loginBean.sessGmail()}" ajax="false" type="submit">
                <h:graphicImage library="resources" name="images/iconGmailBlack.png" style="width: 150px; height: 150px; "/>
                                    <f:param name="idParamtro" value="#{loginBean.Login}" />
                            </h:commandLink>
    

    LoginBean.java

    ....
        private Session Login;
    
        public Session getLogin() {
            return Login;
        }
    
        public void setLogin(Session userLog) {
            this.userLog = Login;
        }
    ....
    

    MainLogin.java

    .....
    @ManagedBean
    @SessionScoped
    public class MainBean {
    
    
        @ManagedProperty(value="#{loginBean}")
        private LoginBean userLogin;
    
        @PostConstruct
        public void init() {
    
                /** Se carga el Login en una variable de MainBean*/
                "variableMainBean" = userLogin.getLogin();
       ...}
    ...}
    

    You also have to configure the application's filters so that you can not access an application URL directly.

    This is to give you an idea of the structure of calls to make the login. There are infinite ways of doing the login since you can put third-party APIs like the one I used to perform the login, in addition to doing all kinds of checks with bbdd, etc.

    If it helps you there are several tutorials (Spanish) on youtube to see directly the different ways you can do them.

        
    answered by 08.09.2016 в 09:29