JSF - Get the SessionScoped Bean instance
Asked Answered
M

2

9

I have this configuration on my web application. 2 beans :

1° Bean - It checks the login;

@ManagedBean(name="login")
@SessionScoped
public class Login {
    private String nickname;
    private String password;
    private boolean isLogged;

    public String getNickname() { return nickname; }
    public void setNickname(String newValue) { nickname=newValue; }

    public String getPassword() { return password; }
    public void setPassword(String newValue) { password=newValue; }

    public void checkLogin() {
        ... i check on db the nickname and the password ...

        if(USER EXIST) {
            isLogged=true;
        } else {
            isLogged=false;
        }

        return true;
    }
}

2° Bean - Manage User parameter :

@ManagedBean(name="user")
@SessionScoped
public class User {
    private String name;
    private String surname;
    private String mail;

    public User() {
        String[] record=null;
        Database mydb=Configuration.getDatabase();
        mydb.connetti();
        ArrayList<String[]> db_result=null;
        db_result=mydb.selectQuery("SELECT name, surname, mail, domicilio FROM users WHERE nickname='???????'");

        int i = 0;
        while (i<db_result.size() ) {
           record=(String[]) db_result.get(i);
           i++;
        }
    }

    ... getter and setter methods...
}

As you can see, I would like to know how get the nickname setted previously on my login bean, so i can do the query on my DB.

In fact i need to get the instance of the current-session bean login : how can I get it? I should use somethings like session.getBean("login") :)

Hope this question is clear :)

Merciful answered 25/11, 2010 at 16:0 Comment(0)
B
12

Use @ManagedProperty to inject it and use @PostConstruct to access it after bean's construction (because in a normal constructor it would be still null).

@ManagedBean
@SessionScoped
public class User {

    @ManagedProperty(value="#{login}")
    private Login login; 

    @PostConstruct
    public void init() {
        // Put original constructor code here.
    }

    // Add/generate getters/setters and other boilerplate.
}

That said, this is not the correct approach. You'd like to do it the other way round. Inject User in Login by @ManagedProperty(value="#{user}") and do the job during submit action method.

You'd also like to put the password in WHERE clause as well. There's absolutely no need to haul the entire users table into Java's memory and determine it one by one. Just let the DB do the job and check if it returns zero or one row.

Bugbee answered 25/11, 2010 at 16:5 Comment(12)
@Gaim: he had the original code where he'd like to access Login bean in the bean's constructor. It would be still null at that point. By the way, the method name doesn't necessarily need to be init(), you can choose whatever you like, as long as there's a @PostConstruct on it.Bugbee
I am not sure but I think that there is missing required setter for the Login - in my applications it is requiredScutate
@Gaim: it's nothing more than obvious to need a getter/setter for this. It's a bean. I've edited the code example so that it's more clear for the ignorants.Bugbee
@Bugbee Yes, I noticed so I deleted my previous commentScutate
Uhm... i use the class User to saved the temporany User's data (name, surname, city, mail, birthday, etc etc) when he show/edit his own profile. I need a sort of bean to retrieve all data. Hope you understand what I saying :)Merciful
So, i need the User Bean, right? You said Just let the DB do the job and check if it returns zero or one row. but i need to save this data, to retrieve them in the profile.xhtml (view context). Of course a user can access to that page only if isLogged is true. that means that i can see only my own profile :)Merciful
Yes, I know. What part don't you understand? Your code seems to be expecting that the DB returns multiple rows. You should also obtain and set the user in checkLogin action method, not in User constructor. I'd also rename the Login to UserManager which has an User property and rename checkLogin() to login(). Anyway, you may find this article useful.Bugbee
Yes, i know that. I don't understand why you are said this :) I write my code to work in this way, ain? I put only the nickname (nickname is singolar in my web application. 2 users can't have same nickname). And i return (or better, i'll save the data) on my bean.Merciful
Ahhh...so you said to put only one Bean, called User. And save it the data instead of have 2 bean? Yeah ok i could do it :) The only problem in your solution is that if im on 2 different browser/pc, and i do two different login, i can't have updated user data (in fact, i put the data/setter to the constructor) :)Merciful
Uhm...but yes...in my example too (if i put it to the constructor) i can't have data updated. This could be a problem...Merciful
I really don't understand your problem about this. Anyway, I'll try to refrain me from commenting on design issues in your future questions. Is your initial question answered/solved? For the remnant just post a new question if you'd like to have more detail.Bugbee
Yes, i was a PHP programmer :) And please, don't refrain, you have helped me in these days, really! Thanks you again. Maybe with this example you can understand : I do the login on chrome. So i save data on a bean (name, surname, ecc ecc). Now i do login on firefox. So i save data on another bean. Ok, now from chrome i edit my profile (so i change database data). If now i go on firefox, my data is not updated, because they are from my last bean (the old ones), not from the updated database. Is it clear what im saying? :) Yeah, maybe i open a new topic about this issue...Merciful
W
9

Also try using the following code:

    ExternalContext tmpEC;
    Map sMap;
    tmpEC = FacesContext.getCurrentInstance().getExternalContext();
    sMap = tmpEC.getSessionMap();
    login loginBean = (login) sMap.get("login");
Wynn answered 28/2, 2012 at 18:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.