JSF捕获会话超时



是否有可能"拦截"会话超时?

我尝试了HttpSessionListener,但据我所知,会话已经被销毁,当httpessionlistener . sessiondestroyed() '方法被调用时。(所以我没有机会确定用户,拥有超时会话)

另一个选项是PhaseListener,检查会话在restoreView-Phase中是否为"新"。

然而,我需要执行一些动作"第二"会话超时-不是在任何以后的刷新,也不是在任何未来的登录。

(后台:需要从某些对象中移除锁,当运行到超时时,用户可能正在处理。)

有办法做到这一点吗?


编辑:尝试1:在sessionbean上使用@PreDestroy:

@SessionScoped
@Named
public class SessionBean1 implements Serializable {
   ...
  @PostConstruct
  private void pconstruct(){
     System.out.println("PostConstructing Session Bean 1");
  }
  @PreDestroy
  public void destroy(){
     System.out.println("PreDestroying Session Bean 1");
  } 
}

 public class SessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        //nothing to do right here.
    }
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("Session Listener says 'destroyed'.");
    }
} 

预期结果:Session超时或用户注销时调用destroy()。

结果:两者都没有发生。

22:29:11,199 INFO  [stdout] (http--0.0.0.0-8090-1) ---- Started RESTORE_VIEW 1 ----
22:29:11,208 INFO  [stdout] (http--0.0.0.0-8090-1) ---- Started RENDER_RESPONSE 6 ----
22:29:11,890 INFO  [stdout] (http--0.0.0.0-8090-1) PostConstructing Session Bean 1
22:29:11,898 INFO  [stdout] (http--0.0.0.0-8090-1) -- Finished Request --
22:30:11,905 INFO  [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) Session Listener says 'destroyed'.

尝试2:试图在SessionListener中拦截会话超时,这显然是在记录超时:

public class SessionListener implements HttpSessionListener {
    @Inject
    private MySession mySession;
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("Destroying Session of owner: " + mySession.getCurrentUser().getShortName());
    }
}

预期结果:仍然可以访问会话bean。

结果:"ContextNotActiveException":

22:38:57,948 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/test]] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) Session event listener threw exception: org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.enterprise.context.SessionScoped
    at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:598) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
    at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:71) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:79) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
    at my.namespace.test$Proxy$_$$_WeldClientProxy.getCurrentUser(MySession$Proxy$_$$_WeldClientProxy.java) [classes:]
    at my.namespace.listener.SessionListener.sessionDestroyed(SessionListener.java:16) [classes:]
    at org.apache.catalina.session.StandardSession.expire(StandardSession.java:690) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.session.StandardSession.isValid(StandardSession.java:585) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.session.ManagerBase.processExpires(ManagerBase.java:390) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.session.ManagerBase.backgroundProcess(ManagerBase.java:375) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1316) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1601) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1610) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1610) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1590) [jbossweb-7.0.13.Final.jar:]
    at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_33]

尝试3:检查会话属性是否可用:

public class SessionListener implements HttpSessionListener {
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        int i=0;
        while (se.getSession().getAttributeNames().hasMoreElements()){
            String name = se.getSession().getAttributeNames().nextElement();
            System.out.println("Checking " + name);
            Object value = se.getSession().getAttribute(name);
            System.out.println("value was: " + value);
            if (i++ == 20){
                break;
            }
        }
    }

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        // nothing to do right here.
    }
}

预期结果:可用属性列表。

result: Infinite Loop:

22:47:48,025 INFO  [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) Checking org.jboss.weld.context.conversation.ConversationIdGenerator
22:47:48,025 INFO  [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) value was: org.jboss.weld.context.conversation.ConversationIdGenerator@1edd87d
22:47:48,026 INFO  [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) Checking org.jboss.weld.context.conversation.ConversationIdGenerator
22:47:48,027 INFO  [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) value was: org.jboss.weld.context.conversation.ConversationIdGenerator@1edd87d
22:47:48,028 INFO  [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) Checking org.jboss.weld.context.conversation.ConversationIdGenerator
22:47:48,029 INFO  [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) value was: org.jboss.weld.context.conversation.ConversationIdGenerator@1edd87d
编辑:

最后,我使用了httpessionlistener并在SessionMap中创建了一个手动条目(除了所有的会话作用域bean之外):FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("user_id", 5)

这个值可以在SessionListener中访问,并允许我关闭给定用户的所有锁。

我尝试了HttpSessionListener,但据我所知,当httpessionlistener . sessiondestroyed() '方法被调用时,会话已经被销毁了。(所以我没有机会确定用户,拥有超时会话)

我不确定这怎么形成一个问题。你仍然有具体的HttpSession实例在你的手中,通过HttpSessionEvent参数,你可以调用getAttribute()方法,为了检查登录的用户,如果它被存储为一个会话属性。

User user = (User) event.getSession().getAttribute("user");
// ...

更新:根据您失败的尝试:

  1. 不知道为什么没有调用@PreDestroy。这将是CDI实现的具体问题。

  2. 你不应该抓取一个注入的@Named实例。相反,您应该直接获取具体实例作为会话属性。在具体管理bean名称上使用HttpSession#getAttribute()

  3. 你在每次迭代中重新创建迭代器。您应该创建它一次,并在每次迭代中重用它。把getAttributeNames()放在while的外面。这个问题与JSF/Servlet无关,只是基本的Java。

我这样做的方法是使UserBean本身成为HttpSessionListener。然后它仍然拥有所有自己的状态,所以它知道它是谁,不管当回调被调用时会话是否仍然具有属性。

相关内容

  • 没有找到相关文章

最新更新