JSF display username when the user login - jsf

How can I display the username from the userindex page once the user successfully login. Should I be pass it to the constructor and use it? or is there any better solution for this?

Create a session-scoped bean that stores either the user's ID (so you can lookup the user per request) or the actual user object itself.
#Named // or #ManagedBean
#SessionScoped
public class SessionGlobals {
private Integer userId;
public boolean isLoggedIn() {
return userId != null;
}
public Integer getUserId() {
return userId;
}
public void login(int userId) {
this.userId = userId;
}
public void logout() {
this.userId = null;
}
Inject this bean wherever it is required. When you login and logout, call the appropriate methods above.
For example:
#Named // or #ManagedBean
#RequestScoped
public class RequestGlobals {
public User getUser() {
return sessionGlobals.isLoggedIn()
? userDao.findById(sessionGlobals.getUserId())
: null;
}
#Inject
private UserDao userDao;
#Inject
private SessionGlobals sessionGlobals;
}
and in your page or template:
<h:outputText value="Welcome, #{requestGlobals.user.firstName}"
rendered="#{sessionGlobals.loggedIn}"/>

Related

Access Session Bean Property/Inject Session Bean

Still learning JSF and Java and having trouble understanding how to access a session bean property.
I have a LoggedUser session bean which sets the user that is logged in(using the login method).
#ManagedBean(name="loggedUser")
#Stateless
#LocalBean
#SessionScoped
public class LoggedUser {
#EJB
UserEJB userEJB;
#PersistenceContext
private EntityManager em;
private UserEntity loggedUser;
private String loginUserName;
private String loginPassword;
public LoggedUser() {}
public UserEntity getLoggedUser() {
return loggedUser;
}
public void setLoggedUser(UserEntity loggedUser) {
this.loggedUser = loggedUser;
}
public String authenticate() {
if (loggedUser == null) {
return "login.xhtml";
} else {
return "";
}
}
public String login() {
if (userEJB.validateLogin(loginUserName, loginPassword)) {
setLoggedUser(userEJB.fetchUser(loginUserName));
return "index.xhtml";
}
return "";
}
public String getLoginUserName() {
return loginUserName;
}
public void setLoginUserName(String loginUserName) {
this.loginUserName = loginUserName;
}
public String getLoginPassword() {
return loginPassword;
}
public void setLoginPassword(String loginPassword) {
this.loginPassword = loginPassword;
}
}
I want to be able to view the logged user from other areas in the application. I think I am injecting it incorrectly because loggedUser is always null when I am in a different bean for example something like..
#Stateless
#LocalBean
public class HistoryEJB {
#PersistenceContext
EntityManager em;
#ManagedProperty(value = "#{loggedUser}")
private LoggedUser loggedUser;
public LoggedUser getLoggedUser() {
return loggedUser;
}
public void setLoggedUser(LoggedUser loggedUser) {
this.loggedUser = loggedUser;
}
public void testLoggedUser() {
loggedUser.getLoggedUser();
// Just an example but would be null here - why?
}
}
How can I access this property from other areas in my application? Thanks for any help.
You can't use #ManagedProperty in an EJB and you shouldn't inject a view component into a business-tier component, period. #ManagedProperty is strictly web-tier stuff and is able to inject only and into web-tier, JSF components.
Your EJB ought to have a method that accepts a LoggedUser. This way, you can then pass your logged-in user to the EJB (which is the proper flow of data in a web application). What you have now is just turning best practice on its head.
So
Add a provideLoggedUser(LoggedUser loggedUser) method to your EJB
Call that method on your instance of UserEJB from within your managed bean
Rule of Thumb: Your EJB should not be aware of the web application
It seems you are missing the setter and getter for loggedUser. In principe it is there but it is convention to name it as follows
setProperty
and
setProperty
for a field named property. Note the capital first letter of the field name in the setter and getter!

Acces one managed bean from another by #ManagedProperty

I have 2 jsf pages and 2 beans for each.
First page is login page, where user types his login-password and then he is redirecting to his mailbox page. I want to get data from login page to mailbox page.
My bean for login page:
#ManagedBean(name = "login")
#ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
#RequestScoped
public class LoginFormBean {
#EJB
private LoginService loginService;
private String email;
private String password;
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
public void setEmail(String email) {
this.email = email;
}
public void setPassword(String password) {
this.password = password;
}
public String login() {
if (loginService.loginUser(email, password))
return "mailBox.xhtml?faces-redirect=true";
else return "";
}
}
My bean for mailbox page:
#ManagedBean(name = "mailBox")
#ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
#RequestScoped
public class MailBoxFormBean {
#ManagedProperty(value = "#{login}")
private LoginFormBean login;
private String email = login.getEmail();
public void setLogin(LoginFormBean login) {
this.login = login;
}
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
}
But when I'm redirecting to mailbox page, login bean is null and I can't get data from it.
What I'm doing wrong?
I've seen a lot of tutorials and answers (for example,
Using #ManagedProperty to call method between Managed beans or
http://www.techartifact.com/blogs/2013/01/access-one-managed-bean-from-another-in-jsf-2-0.html
)
I do exactly the same, but it isn't working for me.
The problem is that your login bean is marked as #RequestScoped, so as soon as you redirect away from the login page, the value is discarded. Try #SessionScoped instead: that's usually the correct scope for user login information.

JSF Bean Property Initialization

I have a managed bean called User which has a String property called name:
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I have another managed bean called UserManager which has a property of type User and allows you to add a user to a user list:
public class UserManager {
private List<User> userList = new ArrayList<User>();
private User user;
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
public String addUser() {
userList.add(user);
return "_USERADDED";
}
}
My JSF page to add the user looks like the following:
<h:form>
<h:inputText value="#{userManager.user.name}"/>
<h:commandButton value="Add User" action="#{userManager.addUser}"/>
</h:form>
The problem I am having is when I run my page and click the "Add User" button I get the following error:
adduser.xhtml #11,50 value="#{userManager.user.name}": Target Unreachable, 'null' returned null
I am assuming this error is due to the fact that the user property in UserManager is null and I am trying to access it to set the property name.
I can get this to work if I modify UserManager and initialize the user property:
private User user = new User();
My question is, is this the correct way to initialize the property or can I do it from within the JSF file and/or a config file?
Yes, you're supposed to create it yourself. JSF/EL won't autocreate nested properties. Canonical approach is to use the #PostConstruct for this.
#ManagedBean
#RequestScoped
public class UserManager {
private List<User> userList = new ArrayList<User>();
private User user;
#PostConstruct
public void init() {
user = new User();
}
public String addUser() {
userList.add(user);
return "_USERADDED";
}
public User getUser() {
return user;
}
}
Note that I omitted the setter as it's never used by JSF/EL. I still wonder what userList is doing there, it doesn't belong there. I'll assume that it's just a stub for testing. In that case, it'd probably better be an application or session scoped bean which you inject by #ManagedProperty.

How to get number of connected users and their role using j_security_check?

I get the username of the connected user (using j_security_check) this way, through a managed bean:
......
username = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal().getName();
And then display it in a jsf page this way : #{userBean.username}
But I figured no way to get the number of connected users and get their role.
In other words, I want to display besides the username, the user role and the number of connected users.
How can I achieve this!?
Thanks in advance for your help!
EDIT:
I can now get the Role of the connected user, using a namedquery in a managed bean :
public Users getUserRole(){
try {
Users auser = (Users)
em.createNamedQuery("Users.findByUsername").
setParameter("username", getRemoteUser()).getSingleResult();
return auser;
} catch (NoResultException nre) {
JsfUtil.addErrorMessage(nre, "getUserRole Error");
return null;
}
}
and in the xhtml page:
<h:outputLabel for="rolefacet" value="Role: "/>
<h:outputFormat id="rolefacet" value="#{UserBean.userRole.ugroup}" />
while ugroup is the role name in the Users entity class.
EDIT: One solution that still does not work for me is to add a HttpSessionListener to my web.xml:
package beans;
/**
*
* #author med81
*/
import java.io.Serializable;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.ArrayList;
import javax.faces.context.FacesContext;
public class SessionCounter implements Serializable, HttpSessionListener {
private List sessions = new ArrayList();
Object s = FacesContext.getCurrentInstance().getExternalContext().getSession(false);
public Object getS() {
return s;
}
public void setS(Object s) {
this.s = s;
}
public SessionCounter() {
}
public void sessionCreated(HttpSessionEvent event) {
HttpSession session = event.getSession();
sessions.add(session.getId());
session.setAttribute("counter", this);
}
public void sessionDestroyed(HttpSessionEvent event) {
HttpSession session = event.getSession();
sessions.remove(session.getId());
session.setAttribute("counter", this);
}
/**
*
* #return size of the session list
*/
public int getActiveSessionNumber() {
return sessions.size();
}
}
Here's a basic kickoff example how you could do it when you're on Servlet 3.0 and thus are able to utilize programmatic login by the new HttpServletRequest#login() API.
The login form: login.xhtml
<h:form>
<h:inputText value="#{user.username}" />
<h:inputSecret value="#{user.password}" />
<h:commandButton value="Login" action="#{user.login}" />
<h:messages />
</h:form>
The user manager bean: com.example.UserManager
#ManagedBean(name="user")
#SessionScoped
public class UserManager implements Serializable {
private String username;
private String password;
private User current;
#EJB
private UserService userService;
#ManagedProperty("#{loginManager.logins}")
private Set<User> logins;
public String login() {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
try {
request.login(username, password);
current = userService.find(username, password);
} catch (ServletException e) {
// Unknown login. Will be handled later in current==null check.
}
if (current == null) {
context.addMessage(null, new FacesMessage("Unknown login"));
return null;
} else {
logins.add(current)
return "home?faces-redirect=true";
}
}
public String logout() {
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
return "login?faces-redirect=true";
}
// ...
}
The logout (and session invalidate) listener: com.example.LogoutListener
#WebListener
public class LogoutListener implements HttpSessionListener {
#Override
public void sessionCreated(HttpSessionEvent event) {
// NOOP.
}
#Override
public void sessionDestroyed(HttpSessionEvent event) {
UserManager userManager = (UserManager) event.getSession().getAttribute("user");
if (userManager != null && userManager.getCurrent() != null) {
userManager.getLogins().remove(userManager.getCurrent());
}
}
}
(Do not do this in logout() method! It's the session invalidation which triggers this, the session invalidation will take place when logout() is called OR when session has expired)
In any logged-in view you can obtain the current user and the login count as follows:
<p>Welcome, #{user.current.name}!</p>
<p>Total logged in users: #{user.logins.size()}</p>
get the number of connected users
I'll assume that you mean to get the number of logged-in users.
Basically, you need to have an applicationwide Set<User> with all logged-in users and add the User to it when it logs in and remove the User when it logs out or when its session is destroyed. Here's an example which uses an application scoped managed bean
#ManagedBean(eager=true)
#ApplicationScoped
public class LoginManager implements Serializable {
private Set<User> users = new HashSet<User>();
public Set<User> getUsers() {
return users;
}
}
If you were using Java EE 6 it would have been easy to replace j_security_check by a managed bean method which utilizes the new Servlet 3.0 HttpServletRequest#login() and simultaneously adds the User to the Set<User> of the injected LoginManager bean.
But on Java EE 5 there is no trivial way to hook on it. You would need to check every request for the logged-in user. Best to achieve this is to put the User object in the session whenever there's an UserPrincipal. You can do this using a filter which does roughly the following job in doFilter() method.
UserPrincipal principal = request.getUserPrincipal();
User user = (User) session.getAttribute("user");
if (principal != null && user == null) {
user = userService.findByName(principal.getName());
session.setAttribute("user", user);
LoginManager loginManager = (LoginManager) servletContext.getAttribute("loginManager");
loginManager.getUsers().add(user);
}
Finally, to remove the user from the logins, best is to hook on HttpSessionListener#sessionDestroyed(), assuming that you're invalidating the session on logout. This will also be called when the session expires.
public void sessionDestroyed(HttpSessionEvent event) {
User user = (User) event.getSession().getAttribute("user");
if (user != null) {
LoginManager loginManager = (LoginManager) event.getSession().getServletContext().getAttribute("loginManager");
loginManager.getUsers().remove(user);
}
}

JSF - Get the SessionScoped Bean instance

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 :)
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.
Also try using the following code:
ExternalContext tmpEC;
Map sMap;
tmpEC = FacesContext.getCurrentInstance().getExternalContext();
sMap = tmpEC.getSessionMap();
login loginBean = (login) sMap.get("login");

Resources