使用监听器监听会话

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cjmust/article/details/83580801

使用监听器监听会话

当会话发生变化时,web容器将通知应用程序这些变化,通过发布订阅模式实现。
如此一来可以将修改会话和监听会话变化的代码解耦。

ServletAPI中定义了几种监听器,通过实现某个监听器的接口来订阅某个事件。
具体配置可以使用部署描述符配置<listener>或者使用注解@javax.servlet.annontation.WebListener(不要同时使用)

Servlet3.0/JEE6开始,可以使用ServletContext的addListener方法以编程的方式注册。


javax.servlet.http.HttpSessionBindingListener接口比较特殊监听器接口,不需要为它配置部署描述符以及注解,如果某个类实现了该接口,那么它自己的状态作为会话特性


最常用的两个会话监听器javax.servlet.http.HttpSessionListener以及javax.servlet.http.HttpSessionIdListener

例如:
创建类SessionListener实现这两个然后添加注解

@WebListener
public class SessionListener implements HttpSessionListener,HttpSessionIdListener{...}

或者在部署描述符(web.xml)中配置

<listener>
 <listener-class>com.test.SessionListener</listener-class>
</listener>
  • 其中HttpSessionListener包含两个方法sessionCreated/sessionDestroyed,sessionCreate将在创建session时调用,sessionDestroyed将在session失效时触发,如调用invalidate方法或过期

  • 其中HttpSessionIdListener包含方法sessionIdChanged,sessionIdChanged将在请求的changeSessionId方法改变会话ID时调用该方法

有时在没有浏览器访问Tomcat的情况下,出现了销毁会话的记录,这是因为Tomcat在关闭时,会把会话持久化到文件系统中,Tomcat在重启时,会把持久化到文件系统的会话恢复,恢复完毕后发现该会话已经过期,触发销毁。

@WebListener
public class SessionListener implements HttpSessionListener, HttpSessionIdListener
{
    private SimpleDateFormat formatter =
            new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss");

    @Override
    public void sessionCreated(HttpSessionEvent e)
    {
        System.out.println(this.date() + ": Session " + e.getSession().getId() +
                " created.");
        SessionRegistry.addSession(e.getSession());
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent e)
    {
        System.out.println(this.date() + ": Session " + e.getSession().getId() +
                " destroyed.");
        SessionRegistry.removeSession(e.getSession());
    }

    @Override
    public void sessionIdChanged(HttpSessionEvent e, String oldSessionId)
    {
        System.out.println(this.date() + ": Session ID " + oldSessionId +
                " changed to " + e.getSession().getId());
        SessionRegistry.updateSessionId(e.getSession(), oldSessionId);
    }

    private String date()
    {
        return this.formatter.format(new Date());
    }
}

public final class SessionRegistry
{
    private static final Map<String, HttpSession> SESSIONS = new Hashtable<>();

    public static void addSession(HttpSession session)
    {
        SESSIONS.put(session.getId(), session);
    }

    public static void updateSessionId(HttpSession session, String oldSessionId)
    {
        synchronized(SESSIONS)
        {
            SESSIONS.remove(oldSessionId);
            addSession(session);
        }
    }

    public static void removeSession(HttpSession session)
    {
        SESSIONS.remove(session.getId());
    }

    public static List<HttpSession> getAllSessions()
    {
        return new ArrayList<>(SESSIONS.values());
    }

    public static int getNumberOfSessions()
    {
        return SESSIONS.size();
    }

    private SessionRegistry()
    {

    }
}

猜你喜欢

转载自blog.csdn.net/cjmust/article/details/83580801