问题描述
|
我通过托管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.0HttpServletRequest#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);
}
}