Han*_*sky 9 jsf j-security-check userprincipal java-ee-5
我通过托管bean以这种方式获取连接用户的用户名(使用j_security_check):
......
username = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal().getName();
Run Code Online (Sandbox Code Playgroud)
然后以这种方式在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;
}
}
Run Code Online (Sandbox Code Playgroud)
并在xhtml页面中:
<h:outputLabel for="rolefacet" value="Role: "/>
<h:outputFormat id="rolefacet" value="#{UserBean.userRole.ugroup}" />
Run Code Online (Sandbox Code Playgroud)
而ugroup是Users实体类中的角色名称.
编辑:一个仍然不适合我的解决方案是在我的web.xml中添加一个HttpSessionListener:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
Bal*_*usC 10
这是一个基本的启动示例,当您使用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>
Run Code Online (Sandbox Code Playgroud)
用户管理器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";
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
注销(和会话无效)监听器: 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());
}
}
}
Run Code Online (Sandbox Code Playgroud)
(不要在logout()方法中执行此操作!会话失效会触发此操作,会话失效将logout()在会话过期时调用OR时发生)
在任何已登录的视图中,您可以获取当前用户和登录计数,如下所示:
<p>Welcome, #{user.current.name}!</p>
<p>Total logged in users: #{user.logins.size()}</p>
Run Code Online (Sandbox Code Playgroud)
获取已连接用户的数量
我假设您的意思是获取登录用户的数量.
基本上,您需要Set<User>具有所有登录用户的应用程序范围,并User在登录时添加它并User在其注销或其会话被销毁时删除.这是一个使用应用程序范围的托管bean的示例
@ManagedBean(eager=true)
@ApplicationScoped
public class LoginManager implements Serializable {
private Set<User> users = new HashSet<User>();
public Set<User> getUsers() {
return users;
}
}
Run Code Online (Sandbox Code Playgroud)
如果您使用的是Java EE 6,那么很容易用j_security_check托管bean方法替换它,它使用新的Servlet 3.0 HttpServletRequest#login()并同时添加User到Set<User>注入的LoginManagerbean中.但是在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);
}
Run Code Online (Sandbox Code Playgroud)
最后,要从登录中删除用户,最好是挂钩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);
}
}
Run Code Online (Sandbox Code Playgroud)