Как узнать количество подключенных пользователей и их роль, используя j_security_check?
Я получаю имя подключенного пользователя (используя j_security_check) таким образом через управляемый компонент:
......
username = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal().getName();
А затем отобразите его на странице jsf следующим образом: #{userBean.username}
Но я никак не мог определить количество подключенных пользователей и получить их роль. Другими словами, я хочу отобразить помимо имени пользователя, роль пользователя и количество подключенных пользователей. Как мне этого добиться!? Заранее спасибо за помощь!
РЕДАКТИРОВАТЬ: теперь я могу получить роль подключенного пользователя, используя именованный запрос в управляемом бине:
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;
}
}
и на странице HTML:
<h:outputLabel for="rolefacet" value="Role: "/>
<h:outputFormat id="rolefacet" value="#{UserBean.userRole.ugroup}" />
в то время как ugroup - это имя роли в классе сущности Users.
РЕДАКТИРОВАТЬ: Одно решение, которое все еще не работает для меня, это добавить HttpSessionListener в мой 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();
}
}
2 ответа
Вот базовый начальный пример того, как вы можете сделать это, когда вы используете Servlet 3.0 и, таким образом, можете использовать программный вход в систему с помощью нового HttpServletRequest#login()
API.
Форма входа: 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>
Пользовательский компонент 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";
}
// ...
}
Прослушиватель выхода из системы (и сессии недействителен): 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());
}
}
}
(Не делайте этого в logout()
метод! Это аннулирование сеанса, которое вызывает это, аннулирование сеанса будет иметь место, когда logout()
называется ИЛИ, когда сессия истекла)
В любом режиме входа в систему вы можете получить текущего пользователя и количество логинов следующим образом:
<p>Welcome, #{user.current.name}!</p>
<p>Total logged in users: #{user.logins.size()}</p>
получить количество подключенных пользователей
Я предполагаю, что вы хотите получить количество вошедших в систему пользователей.
По сути, вам нужно иметь приложение по всему Set<User>
со всеми зарегистрированными пользователями и добавить User
к нему, когда он входит в систему и удаляет User
когда он выходит из системы или когда его сеанс уничтожен. Вот пример, в котором используется управляемый компонент приложения
@ManagedBean(eager=true)
@ApplicationScoped
public class LoginManager implements Serializable {
private Set<User> users = new HashSet<User>();
public Set<User> getUsers() {
return users;
}
}
Если бы вы использовали Java EE 6, это было бы легко заменить j_security_check
методом управляемого бина, который использует новый Servlet 3.0 HttpServletRequest#login()
и одновременно добавляет User
к Set<User>
из введенных LoginManager
боб. Но в Java EE 5 нет тривиального способа зацепить его. 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()
метод.
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);
}
}