2017-01-09 72 views
0

我有一个使用Wildfly 10作为服务器的JSF 2.2应用程序。会话未正确无效,抛出“会话无效”

用户已登录,并添加到在线用户列表:

HttpSession session = request.getSession(); 
funcionario.setSessao(session); 
funcionario.setIp(request.getRemoteAddr()); 
session.setAttribute("usuarioLogado", funcionario); 

我删除从在线用户列表中注销用户。

public class ActiveUserListener implements HttpSessionAttributeListene { 

@Inject 
Fixo fixo; 

@Override 
public void attributeAdded(HttpSessionBindingEvent event) { 
    if (event.getValue() instanceof Funcionario) { 
     fixo.getLogins().add((Funcionario) event.getValue()); 

    } 
} 

@Override 
public void attributeRemoved(HttpSessionBindingEvent event) { 
    if (event.getValue() instanceof Funcionario) { 
     if (event.getValue() instanceof Funcionario) { 
      fixo.getLogins().remove((Funcionario) event.getValue()); 
     } 
    } 
} 

@Override 
public void attributeReplaced(HttpSessionBindingEvent event) { 
    if (event.getValue() instanceof Funcionario) { 
     fixo.getLogins().add((Funcionario) event.getValue()); 
    } 
} } 

public class SessionCounter implements HttpSessionListener { 

@Inject 
Fixo fixo; 

public void sessionDestroyed(HttpSessionEvent se) { 
    if (se.getSession().getAttribute("usuarioLogado") != null) {    
     Funcionario f = fixo.getLogins().stream().filter(o -> o.getSessaoId().equals(se.getSession().getId())) 
       .findAny().get(); 
     fixo.getLogins().remove(f); 

    } 
} 

@Override 
public void sessionCreated(HttpSessionEvent arg0) { 
    // TODO Auto-generated method stub 

}}´ 

,当我尝试打印一些用户/会话的详细信息:

public void usuConsole() { 
     System.out.println("nº " + fixo.getLogins().size()); 
     for (Funcionario f : fixo.getLogins()) { 
      System.out.println(f.getMatricula()); 
      if (f.getSessao() != null) { 
       System.out.println(f.getSessao().getId()); 
       System.out.println(f.getSessao().getCreationTime()); 
       System.out.println(f.getSessao().getLastAccessedTime()); 
      } 
     } 
    } 

打印一些线条,在某些时候:

会话无效R5EB6hKAzanm50PSRYqxcv361UMD6nGjZWxJVc5P

如果很少用户登录就没问题,但是在很多用户登录之后d注销,错误出现

+0

你是否试图让这个线程安全?如果同时创建多个会话或同时创建一些会话,会发生什么情况? – stdunbar

+0

不,我该怎么办? – erickdeoliveiraleal

回答

0

选项1:

尝试使用java.util.concurrent.CopyOnWriteArrayList中实现你的登录集合中的Fixo类。

选项2

手动同步登录集合:

a)使用的对象进行同步时使所述收集最终(好的做法

b)中同步的登录收集刀片和。删除事件监听器方法:

synchronized(fixo.getLogins()){ 
    fixo.getLogins().remove((Funcionario) event.getValue()); 
} 

synchronized(fixo.getLogins()){ 
    fixo.getLogins().add((Funcionario) event.getValue()); 
} 

c)Synchroniz E中的每一个循环:

synchronized(fixo.getLogins()){ 

    for (Funcionario f : fixo.getLogins()) { 
     System.out.println(f.getMatricula()); 
     if (f.getSessao() != null) { 
      System.out.println(f.getSessao().getId()); 
      System.out.println(f.getSessao().getCreationTime()); 
      System.out.println(f.getSessao().getLastAccessedTime()); 
     } 
    } 
} 

现在,而在任何这些synchronized块,任何公开的方法调用进行登录集合将被阻塞,直到应用程序走出块。 这意味着虽然for each循环正在运行,但事件侦听器方法中集合的任何修改都将保留,直到循环结束。 根据监听器规范,会话将不会失效,直到sessionDestroyed方法完成处理。

这就是至少这个理论,试试看,看看它是如何去的。

+0

我将列表更改为,现在我在线程“default task-79”中出现异常java.lang.RuntimeException:org.jboss.weld.exceptions.UnsatisfiedResolutionException:WELD-001334:类型为HttpSessionContext的不满足依赖关系,带限定词' – erickdeoliveiraleal

+0

*** ..将列表更改为java.util.concurrent.CopyOnWriteArrayList – erickdeoliveiraleal

+0

并且会话无效的问题仍然存在。 – erickdeoliveiraleal