Как узнать количество подключенных пользователей и их роль, используя j_security_check? - PullRequest
9 голосов
/ 26 мая 2011

Я получаю имя подключенного пользователя (используя j_security_check) таким образом через управляемый компонент:

......
    username =   FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal().getName();

А затем отобразить его на странице jsf следующим образом: #{userBean.username} Но я никак не мог получить количество подключенных пользователей и получить их роль. Другими словами, я хочу отобразить помимо имени пользователя, роль пользователя и количество подключенных пользователей . Как мне этого добиться !? Заранее спасибо за помощь!

EDIT: Теперь я могу получить роль подключенного пользователя, используя именованный запрос в управляемом компоненте:

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;
        }

    }

и на странице xhtml:

<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 ]

10 голосов
/ 06 июля 2011

Вот базовый начальный пример того, как вы можете сделать это, когда вы используете 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>
7 голосов
/ 26 мая 2011

получить количество подключенных пользователей

Я предполагаю, что вы хотите получить количество вошедших в систему пользователей.

По сути, вам нужно иметь приложение 1009 * со всеми вошедшими в систему пользователями и добавить к нему 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 на метод управляемого компонента, который используетновый сервлет 3.0 HttpServletRequest#login() и одновременно добавляет User к Set<User> введенного компонента LoginManager.Но на Java EE 5 нет тривиального способа зацепить его.Вам нужно будет проверять каждый запрос вошедшего в систему пользователя.Лучше всего добиться этого - помещать объект User в сеанс всякий раз, когда есть UserPrincipal.Вы можете сделать это, используя фильтр , который примерно выполняет следующую работу в методе 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);
}

Наконец, чтобы удалить пользователя из логинов, лучше всего подключить HttpSessionListener#sessionDestroyed(), при условии, что вы отменяете сеанс при выходе из системы.Это также будет вызвано, когда сессия истечет.

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);
    }
}
...