Search code examples
jsfmanaged-bean

Show how many Users logged in with JSF


i trie to run this code

@ManagedBean
@ApplicationScoped
public class Controller implements Serializable {

private static final long serialVersionUID = 1L;

private Benutzer benutzer;

private List<Erfasst> bisherErfasst = new ArrayList<Erfasst>();

private EntityManagerFactory emf = Persistence
        .createEntityManagerFactory("CP Kontrolle");
private static Controller instance = new Controller();

public Benutzer getBenutzer() {
    return benutzer;
}

public boolean anmelden(String email, int kdnr) {
    EntityManager em = emf.createEntityManager();
    Query query = em
            .createQuery("SELECT b FROM Benutzer b WHERE b.email = :email AND b.kdnr = :kdnr");
    query.setParameter("email", email);
    query.setParameter("kdnr", kdnr);
    List<Benutzer> liste = query.getResultList();
    em.close();
    if (liste.size() == 1) {
        benutzer = liste.get(0);
        AngemeldeteBenutzer.getAb().hinzufuegen(benutzer);

        return true;
    } else {
        return false;
    }
}

public static Controller getInstance() {
    return instance;
}
  [....]
}

}

The above code is my ControllerBean. From the Login-Form, user data will be checked in the "anmelden" Class and return true or false if it was successfully.If successfully, the user will be store into a list, as you can see.

@ManagedBean
@ApplicationScoped
public class AngemeldeteBenutzer implements Serializable {

private static final long serialVersionUID = 1L;

private List<Benutzer> online = new LinkedList<Benutzer>();
private static AngemeldeteBenutzer ab = new AngemeldeteBenutzer();

public static AngemeldeteBenutzer getAb() {
    return ab;
}

public List<Benutzer> getOnline() {
    return online;
}

public void hinzufuegen(Benutzer benutzer) {
    online.add(benutzer);

}

}

This is my other Bean, which store the successfully logged user into a list. Now i want to list all user into my table, but my table is still empty. No errors!

    <h:panelGrid columns="2" id="onlinePanel" >
        <h:dataTable value="#{angemeldeteBenutzer.online}" var="on">
            <h:column>
                <f:facet name="header">Email</f:facet>
                <h:outputText value="#{on.email}"></h:outputText>
            </h:column>
        </h:dataTable>
    </h:panelGrid>

Solution

  • The mistake is here:

    private static Controller instance = new Controller();
    
    public static Controller getInstance() {
        return instance;
    }
    
    private static AngemeldeteBenutzer ab = new AngemeldeteBenutzer();
    
    public static AngemeldeteBenutzer getAb() {
        return ab;
    }
    

    You seem to have missed the point of a bean management framework with dependency injection support. You seem to be expecting that #{angemeldeteBenutzer} in the JSF page is referring exactly the same instance as you manually created there with new operator and are filling with users.

    This is Wrong! You have there two instances of the class, one automatically created by JSF and available via #{angemeldeteBenutzer} and another one manually created by yourself and available via that getAb() method only.

    Get rid of all those static fields and methods. They don't belong there. Instead, use @ManagedProperty to let JSF inject managed beans in each other. Add this code to the Controller class.

    @ManagedProperty("#{angemeldeteBenutzer}")
    private AngemeldeteBenutzer ab;
    
    public AngemeldeteBenutzer getAb() {
        return ab;
    }
    
    public void setAb(AngemeldeteBenutzer ab) {
        this.ab = ab;
    }
    

    And replace in the same Controller class this line

    AngemeldeteBenutzer.getAb().hinzufuegen(benutzer);
    

    by

    ab.hinzufuegen(benutzer);
    

    Note: if you're already on Java EE 7, consider using CDI @Named instead of JSF @ManagedBean. When injecting via @Inject instead of @ManagedProperty, you don't need those ugly getter/setter anymore.

    @Named
    @ApplicationScoped
    public class AngemeldeteBenutzer {
    }
    
    @Named
    @ApplicationScoped
    public class Controller {
    
        @Inject
        private AngemeldeteBenutzer ab;
    
    }
    

    Unrelated to the concrete problem, the Controller doesn't seem to be a legit application scoped bean. It looks too much like a view scoped bean due that view-specific variables and business logic. Make sure you understand the scopes: How to choose the right bean scope?