servlet · 2024-10-31 0

servlet 创建 session 和 销毁 session

1.创建 session

执行 request.getSession() 时

// RequestFacade.java
@Override
public HttpSession getSession() {
    checkFacade();
    return getSession(true);
}

@Override
public HttpSession getSession(boolean create) {
    checkFacade();
    ...
    return request.getSession(create);
}
// Request.java
@Override
public HttpSession getSession(boolean create) {
    Session session = doGetSession(create);
    if (session == null) {
        return null;
    }

    return session.getSession();
}

protected Session doGetSession(boolean create) {
    Context context = getContext();
    if (context == null) {
        return null;
    }

    if ((session != null) && !session.isValid()) {
        session = null;
    }
    if (session != null) {
        return session;
    }

    Manager manager = context.getManager();
    if (manager == null) {
        return null;
    }
    if (requestedSessionId != null) {
        try {
            session = manager.findSession(requestedSessionId);
        }
        ...
        if ((session != null) && !session.isValid()) {
            session = null;
        }
        if (session != null) {
            session.access();
            return session;
        }
    }

    if (!create) {
        return null;
    }
    ...    
    session = manager.createSession(sessionId);

    if (session != null && trackModesIncludesCookie) {
        Cookie cookie =
                ApplicationSessionCookieConfig.createSessionCookie(context, session.getIdInternal(), isSecure());

        response.addSessionCookieInternal(cookie);
    }

    if (session == null) {
        return null;
    }

    session.access();
    return session;
}
// StandardManager.java
@Override
public Session findSession(String id) throws IOException {
    if (id == null) {
        return null;
    }
    return sessions.get(id);
}

@Override
public Session createSession(String sessionId) {
    ...
    Session session = createEmptySession();

    session.setNew(true);
    session.setValid(true);
    session.setCreationTime(System.currentTimeMillis());
    session.setMaxInactiveInterval(getContext().getSessionTimeout() * 60);
    String id = sessionId;
    if (id == null) {
        id = generateSessionId();
    }
    session.setId(id);
    sessionCounter++;

    SessionTiming timing = new SessionTiming(session.getCreationTime(), 0);
    synchronized (sessionCreationTiming) {
        sessionCreationTiming.add(timing);
        sessionCreationTiming.poll();
    }
    return session;
}
// StandardSession.java
@Override
public void setId(String id, boolean notify) {

    if ((this.id != null) && (manager != null)) {
        manager.remove(this);
    }

    this.id = id;

    if (manager != null) {
        manager.add(this);
    }

    if (notify) {
        tellNew();
    }
}

public void tellNew() {
    fireSessionEvent(Session.SESSION_CREATED_EVENT, null);

    Context context = manager.getContext();
    Object listeners[] = context.getApplicationLifecycleListeners();
    if (listeners != null && listeners.length > 0) {
        HttpSessionEvent event = new HttpSessionEvent(getSession());
        for (Object o : listeners) {
            if (!(o instanceof HttpSessionListener)) {
                continue;
            }
            HttpSessionListener listener = (HttpSessionListener) o;
            try {
                context.fireContainerEvent("beforeSessionCreated", listener);
                listener.sessionCreated(event);
                context.fireContainerEvent("afterSessionCreated", listener);
            } catch (Throwable t) {
                ...
                manager.getContext().getLogger().error(sm.getString("standardSession.sessionEvent"), t);
            }
        }
    }

}

2.销毁 session

销毁方式:
1) 执行 request.getSession().invalidate()
2) 过期销毁

// StandardSessionFacade.java
@Override
public void invalidate() {
    session.invalidate();
}
// StandardSession.java
@Override
public void invalidate() {
    ...
    expire();
}

public void expire(boolean notify) {
    if (!isValid) {
        return;
    }

    synchronized (this) {
        if (expiring || !isValid) {
            return;
        }

        if (manager == null) {
            return;
        }

        expiring = true;

        Context context = manager.getContext();

        if (notify) {
            ...
            try {
                ...
                if (listeners != null && listeners.length > 0) {
                    HttpSessionEvent event = new HttpSessionEvent(getSession());
                    for (int i = 0; i < listeners.length; i++) {
                        int j = (listeners.length - 1) - i;
                        if (!(listeners[j] instanceof HttpSessionListener)) {
                            continue;
                        }
                        HttpSessionListener listener = (HttpSessionListener) listeners[j];
                        try {
                            context.fireContainerEvent("beforeSessionDestroyed", listener);
                            listener.sessionDestroyed(event);
                            context.fireContainerEvent("afterSessionDestroyed", listener);
                        } catch (Throwable t) {
                            ...
                        }
                    }
                }
            } finally {
                ...
            }
        }
        ...
        manager.remove(this, true);
        ...        
        setValid(false);
        expiring = false;
        ...
        if (notify) {
            fireSessionEvent(Session.SESSION_DESTROYED_EVENT, null);
        }
        ...
    }

}
// StandardManager.java
@Override
public void remove(Session session, boolean update) {
    if (update) {
        ...
    }

    if (session.getIdInternal() != null) {
        sessions.remove(session.getIdInternal());
    }
}

3.设置 session 有效时间

通过 setMaxInactiveInterval 设置 session 有效时间 60s

request.getSession().setMaxInactiveInterval(60);