首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java EE 6并发会话和共享

Java EE 6并发会话和共享
EN

Stack Overflow用户
提问于 2012-07-17 05:13:46
回答 3查看 1.1K关注 0票数 2

我正在开发一个使用Java EE 6 (JSF CDI EJB)的web应用程序,它不应该允许并发登录(相同的用户和通过)。

我喜欢的是:

如果用户登录两次,则需要使第一个会话无效,并且旧会话数据(包括所有具有SessionScope或其他作用域(如Apache CODI中的WindowScope )的CDI都将传输到新会话。

这有点像一种想要的会话劫持方法:-)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-07-17 19:05:13

我用一个过滤器解决了这个问题。

公共类SessionReplicationFilter实现筛选器{

代码语言:javascript
复制
@Inject
SessionReplicationManager manager;

public SessionReplicationFilter() {
}


@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
    //Process chain first 
    if (chain != null) {
        chain.doFilter(request, response);
    }

    //check http request
    if (request instanceof HttpServletRequest) {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        // Retrieve the session and the principal (authenticated user)
        // The principal name is actually the username
        HttpSession session = httpRequest.getSession();
        Principal principal = httpRequest.getUserPrincipal();
        if (principal != null && principal.getName() != null && session != null) {
            manager.checkExistingSession(principal.getName(), session)) 
        }
    }

}

@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void destroy() {

}

}

管理器如下所示

@ApplicationScoped公共类SessionReplicationManager {

代码语言:javascript
复制
private Map<String, HttpSession> map = new ConcurrentHashMap<String, HttpSession>();


public boolean checkExistingSession(String user, HttpSession session) {
    if (map.keySet().contains(user)) {
        if (!session.getId().equals(map.get(user).getId())) {
            System.out.println("User already logged in ");
            HttpSession oldSession = map.get(user);
            // copies all attributes from the old session to the new session (replicate the session)
            Enumeration<String> enumeration = oldSession.getAttributeNames();
            while (enumeration.hasMoreElements()) {
                String name = enumeration.nextElement();
                System.out.println("Chaning attribut " + name);
                session.setAttribute(name, oldSession.getAttribute(name));
            }
            // invalidates the old user session (this keeps one session per user)
            oldSession.invalidate();
            map.put(user, session);
            return true;
        }
    } else {
        System.out.println("Putting "+user+" into session cache");
        map.put(user, session);
        return false;
    }
    return false;
}

}

它可以很好地与CoDI ViewScoped注释Bean配合使用

如果第一个用户失效,则每个(AJAX)请求都会导致会话过期异常,即使使用restore session按钮也可以轻松处理该异常

视图范围内的bean唯一的小问题是,它们会获得一个新的视图id。通过将它们改回原始值,一切都会正常工作。

我需要补充的是:

  • 自动注销( ajax轮询,websockets,...)
  • 某种注册表,其中存储了所有

此注释中缺少:

configuration的

  • web.xml

问候

票数 0
EN

Stack Overflow用户

发布于 2012-07-17 14:43:59

在JavaEE6中没有这方面的固有机制。

因为我不能想象你想要将正在进行的用例(例如一个开放的结帐过程)从一个会话转移到另一个会话,我建议你简单地跟踪用户的图形用户界面状态

对于这一点,RESTful URL听起来是一个理想的方法。保存上一个用户URL /用户操作(例如www.myapp.com/orders/new/12),并在新登录时重新打开它。

如果你不想把它保存在数据库中,一个应用程序作用域的映射userid / url可能是最好的办法。

票数 0
EN

Stack Overflow用户

发布于 2012-07-17 16:42:54

您可以为用户使用无状态bean,因此每当用户尝试登录/重新登录时,当前会话都会失效(在登录过程的开始)

考虑这种方法:

代码语言:javascript
复制
try {           
   session = request.getSession();   //the request is passed by another page or action
   if(session.getAttribute("user") != null) {

           //your code to forward or handle the existing user (re-log in/ do nothing etc.)
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11512657

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档