如何使用j_security_check获取已连接用户的数量及其角色?

问题描述

| 我通过托管bean以这种方式获取已连接用户的用户名(使用j_security_check):
......
    username =   FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal().getName();
然后以这种方式在jsf页面中显示:
#{userBean.username}
但我想不出任何办法来获得已连接用户的数量并获得他们的角色。 换句话说,除了用户名,用户角色和连接的用户数之外,我还要显示。 我该如何实现!! 在此先感谢您的帮助! 编辑: 现在,我可以使用托管bean中的namedquery来获取连接用户的角色:
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();
    }


}
    

解决方法

这是一个基本的启动示例,当您使用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>
    ,  获取连接的用户数 我假设您的意思是获取已登录用户的数量。 基本上,您需要在应用程序范围内拥有所有登录用户的ѭ15,并在其登录时将ѭ16添加到其中,并在注销或会话被破坏时删除ѭ16。这是一个使用应用程序范围的托管Bean的示例
@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,将很容易通过托管bean方法替换
j_security_check
,该方法利用新的Servlet 3.0
HttpServletRequest#login()
,同时将
User
添加到注入的
LoginManager
bean的
Set<User>
中。 但是在Java EE 5上,没有简单的方法可以挂在它上面。您将需要检查登录用户的每个请求。最好的实现方法是在有
UserPrincipal
的情况下将
User
对象放入会话中。您可以使用过滤器执行此操作,该过滤器在
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);
}
最后,要从登录名中删除用户,最好是钩上“ѭ28”,假设您在注销时使会话无效。会话期满时也会调用此方法。
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);
    }
}
    

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...