91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何創建session對象

發布時間:2022-09-28 15:02:22 來源:億速云 閱讀:579 作者:iii 欄目:編程語言

這篇文章主要介紹“如何創建session對象”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“如何創建session對象”文章能幫助大家解決問題。

Session對象的創建一般是源于這樣的一條語句:

Session session = request.getSession(false);或者Session session = request.getSession();如果不在乎服務器壓力可能多那么一點點的話。

在Tomcat的實現中,這個request是org.apache.catalina.connector.Request類的包裝類org.apache.catalina.connector.RequestFacade的對象,它的兩個#getSession()方法如下:

public HttpSession getSession(boolean create) {  
    if (request == null) {  
        throw new IllegalStateException(  
                        sm.getString("requestFacade.nullRequest"));  
    }    
    if (SecurityUtil.isPackageProtectionEnabled()){  
        return (HttpSession)AccessController.  
            doPrivileged(new GetSessionPrivilegedAction(create));  
    } else {  
        return request.getSession(create);  
    }  
}
public HttpSession getSession() {  
    if (request == null) {  
        throw new IllegalStateException(  
                        sm.getString("requestFacade.nullRequest"));  
    }    
    return getSession(true);  
}

其實差不太多,最后都會進入org.apache.catalina.connector.Request的#getSession()方法。這個方法的源代碼如下:

public HttpSession getSession(boolean create) {  
    Session session = doGetSession(create);  
    if (session != null) {  
        return session.getSession();  
    } else {  
        return null;  
    }  
}

然后調用就到了#doGetSession()這個方法了。源代碼如下

protected Session doGetSession(boolean create) {  
    // 沒有Context的話直接返回null  
    if (context == null)  
        return (null);    
    // 判斷Session是否有效  
    if ((session != null) && !session.isValid())  
        session = null;  
    if (session != null)  
        return (session);    
    // 返回Manager對象,這里是StandardManager類的對象  
    Manager manager = null;  
    if (context != null)  
        manager = context.getManager();  
    if (manager == null)  
        return (null); // Sessions are not supported  
    // 判斷是否有SessionID  
    if (requestedSessionId != null) {  
        try {  
            // 在Manager中根據SessionID查找Session  
            session = manager.findSession(requestedSessionId);  
        } catch (IOException e) {  
            session = null;  
        }  
        if ((session != null) && !session.isValid())  
            session = null;  
        if (session != null) {  
            // 更新訪問時間  
            session.access();  
            return (session);  
        }  
    }    
    // 創建新的Session  
    if (!create)  
        return (null);  
    if ((context != null) && (response != null) && context.getCookies()  
            && response.getResponse().isCommitted()) {  
        throw new IllegalStateException(sm.getString("coyoteRequest.sessionCreateCommitted"));  
    }    
    // 判斷是否使用 "/" 作為Session Cookie的存儲路徑 并且 是否SessionID來自Cookie  
    if (connector.getEmptySessionPath() && isRequestedSessionIdFromCookie()) {  
        // 創建Session  
        session = manager.createSession(getRequestedSessionId());  
    } else {  
        session = manager.createSession(null);  
    }    
    // 創建一個新的Session Cookies  
    if ((session != null) && (getContext() != null) && getContext().getCookies()) {  
        Cookie cookie = new Cookie(Globals.SESSION_COOKIE_NAME, session.getIdInternal());  
        // 配置Session Cookie  
        configureSessionCookie(cookie);  
        // 在響應中加入Session Cookie  
        response.addCookieInternal(cookie);  
    }    
    if (session != null) {  
        // 更新訪問時間  
        session.access();  
        return (session);  
    } else {  
        return (null);  
    }    
}

這個方法說明了Session創建的大致過程,首先判斷requestedSessionId是否存在,如果存在,那么根據這個ID去查找Session對象。如果requestedSessionId不存在或者沒有取到Session,并且傳遞給#getSession(boolean)的參數為真,那么要創建一個新的Session,并且給客戶端寫回去一個Session Cookie。

首先,我感興趣的是requestedSessionId的賦值,它到底是什么時候被賦值的呢?

還要向回看Tomcat的請求處理過程,請求曾到過這一步,org.apache.catalina.connector.CoyoteAdapter的#service()方法。里邊有這樣一句方法調用:postParseRequest(req, request, res, response)。就是這一步處理了SessionID的獲取,這個方法調用了#parseSessionId()和parseSessionCookiesId()這兩個方法,就是它對Session ID進行了提取,源代碼分別如下:

protected void parseSessionId(org.apache.coyote.Request req, Request request) {    
    ByteChunk uriBC = req.requestURI().getByteChunk();  
    // 判斷URL中是不是有";jsessionid="這個字符串  
    int semicolon = uriBC.indexOf(match, 0, match.length(), 0);   
    if (semicolon > 0) {  
        // Parse session ID, and extract it from the decoded request URI  
        // 在URL中提取Session ID  
        int start = uriBC.getStart();  
        int end = uriBC.getEnd();    
        int sessionIdStart = semicolon + match.length();  
        int semicolon2 = uriBC.indexOf(';', sessionIdStart);  
        if (semicolon2 >= 0) {  
            request.setRequestedSessionId(new String(uriBC.getBuffer(), start + sessionIdStart,  
                    semicolon2 - sessionIdStart));  
            byte[] buf = uriBC.getBuffer();  
            for (int i = 0; i < end - start - semicolon2; i++) {  
                buf[start + semicolon + i] = buf[start + i + semicolon2];  
            }  
            uriBC.setBytes(buf, start, end - start - semicolon2 + semicolon);  
        } else {  
            request.setRequestedSessionId(new String(uriBC.getBuffer(), start + sessionIdStart,  
                    (end - start) - sessionIdStart));  
            uriBC.setEnd(start + semicolon);  
        }  
        // 設定Session ID來自于URL  
        request.setRequestedSessionURL(true);    
    } else {  
        request.setRequestedSessionId(null);  
        request.setRequestedSessionURL(false);  
    }    
}
protected void parseSessionCookiesId(org.apache.coyote.Request req, Request request) {  
    Context context = (Context) request.getMappingData().context;  
    if (context != null && !context.getCookies())  
        return;    
    // 返回Cookie  
    Cookies serverCookies = req.getCookies();  
    int count = serverCookies.getCookieCount();  
    if (count <= 0)  
        return;    
    for (int i = 0; i < count; i++) {  
        ServerCookie scookie = serverCookies.getCookie(i);  
        // 判斷是否有JSESSIONID這個名字的Cookie  
        if (scookie.getName().equals(Globals.SESSION_COOKIE_NAME)) {  
            // Override anything requested in the URL  
            if (!request.isRequestedSessionIdFromCookie()) {  
                // 設定Session ID  
                convertMB(scookie.getValue());  
                request.setRequestedSessionId(scookie.getValue().toString());  
                // 如果之前在URL中讀到了SessionID,那么會覆蓋它  
                request.setRequestedSessionCookie(true);  
                request.setRequestedSessionURL(false);  
                if (log.isDebugEnabled())  
                    log.debug(" Requested cookie session id is " + request.getRequestedSessionId());  
            } else {  
                if (!request.isRequestedSessionIdValid()) {  
                    convertMB(scookie.getValue());  
                    request.setRequestedSessionId(scookie.getValue().toString());  
                }  
            }  
        }  
    }    
}

Tomcat就是通過上邊的兩個方法讀到URL或者Cookie中存放的Session ID的。

了解了Session ID的獲取,下面要看一下Session的查找過程,就是org.apache.catalina.session.StandardManager的#findSession()方法。這個方法是在它的基類中定義的,源代碼如下:

public Session findSession(String id) throws IOException {  
    if (id == null)  
        return (null);  
    return (Session) sessions.get(id);  
}

代碼很短,其中sessions是一個ConcurrentHashMap<String, Session>對象。那么這個sessions的對象是什么時候載入的Session呢?

啟動的時候!可以看一下StandardManager#start()方法。最后調用了#load()方法,這個就是載入Session的方法了:

public void load() throws ClassNotFoundException, IOException {  
    if (SecurityUtil.isPackageProtectionEnabled()) {  
        try {  
            AccessController.doPrivileged(new PrivilegedDoLoad());  
        } catch (PrivilegedActionException ex) {  
            Exception exception = ex.getException();  
            if (exception instanceof ClassNotFoundException) {  
                throw (ClassNotFoundException) exception;  
            } else if (exception instanceof IOException) {  
                throw (IOException) exception;  
            }  
            if (log.isDebugEnabled())  
                log.debug("Unreported exception in load() " + exception);  
        }  
    } else {  
        doLoad();  
    }  
}

最后調用了#doLoad()方法來具體的載入Session,源代碼如下:

protected void doLoad() throws ClassNotFoundException, IOException {  
    if (log.isDebugEnabled())  
        log.debug("Start: Loading persisted sessions");    
    // 清空Map  
    sessions.clear();    
    // 對應work/Catalina/localhost/%app name%/SESSIONS.ser文件  
    File file = file();  
    if (file == null)  
        return;  
    if (log.isDebugEnabled())  
        log.debug(sm.getString("standardManager.loading", pathname));  
    FileInputStream fis = null;  
    ObjectInputStream ois = null;  
    Loader loader = null;  
    ClassLoader classLoader = null;  
    try {  
        // 載入Session緩存文件  
        fis = new FileInputStream(file.getAbsolutePath());  
        BufferedInputStream bis = new BufferedInputStream(fis);  
        if (container != null)  
            loader = container.getLoader();  
        if (loader != null)  
            classLoader = loader.getClassLoader();  
        if (classLoader != null) {  
            if (log.isDebugEnabled())  
                log.debug("Creating custom object input stream for class loader ");  
            ois = new CustomObjectInputStream(bis, classLoader);  
        } else {  
            if (log.isDebugEnabled())  
                log.debug("Creating standard object input stream");  
            ois = new ObjectInputStream(bis);  
        }  
    } catch (FileNotFoundException e) {  
        if (log.isDebugEnabled())  
            log.debug("No persisted data file found");  
        return;  
    } catch (IOException e) {  
        log.error(sm.getString("standardManager.loading.ioe", e), e);  
        if (ois != null) {  
            try {  
                ois.close();  
            } catch (IOException f) {  
                ;  
            }  
            ois = null;  
        }  
        throw e;  
    }    
    synchronized (sessions) {  
        try {  
            // 讀出Session個數  
            Integer count = (Integer) ois.readObject();  
            int n = count.intValue();  
            if (log.isDebugEnabled())  
                log.debug("Loading " + n + " persisted sessions");  
            //  讀入Session  
            for (int i = 0; i < n; i++) {  
                StandardSession session = getNewSession();  
                session.readObjectData(ois);  
                session.setManager(this);  
                sessions.put(session.getIdInternal(), session);  
                session.activate();  
                sessionCounter++;  
            }  
        } catch (ClassNotFoundException e) {  
            log.error(sm.getString("standardManager.loading.cnfe", e), e);  
            if (ois != null) {  
                try {  
                    ois.close();  
                } catch (IOException f) {  
                    ;  
                }  
                ois = null;  
            }  
            throw e;  
        } catch (IOException e) {  
            log.error(sm.getString("standardManager.loading.ioe", e), e);  
            if (ois != null) {  
                try {  
                    ois.close();  
                } catch (IOException f) {  
                    ;  
                }  
                ois = null;  
            }  
            throw e;  
        } finally {  
            try {  
                if (ois != null)  
                    ois.close();  
            } catch (IOException f) {  
            }  
  
            // 刪除Session緩存文件  
            if (file != null && file.exists())  
                file.delete();  
        }  
    }    
    if (log.isDebugEnabled())  
        log.debug("Finish: Loading persisted sessions");  
}

大致知道了Session的讀取過程,后面就是Session沒找到時創建Session的過程了。具體就是org.apache.catalina.session.StandardManager的#createSession()方法:

public Session createSession(String sessionId) {  
    if ((maxActiveSessions >= 0) && (sessions.size() >= maxActiveSessions)) {  
        rejectedSessions++;  
        throw new IllegalStateException(sm.getString("standardManager.createSession.ise"));  
    }  
    return (super.createSession(sessionId));  
}

最后調用到了它的基類的#createSession()方法了。

public Session createSession(String sessionId) {  
    // 創建一個新的Session  
    Session session = createEmptySession();    
    // 初始化Session的屬性  
    session.setNew(true);  
    session.setValid(true);  
    session.setCreationTime(System.currentTimeMillis());  
    session.setMaxInactiveInterval(this.maxInactiveInterval);  
    // 如果Session ID為null,那么就生成一個  
    if (sessionId == null) {  
        sessionId = generateSessionId();  
    }  
    session.setId(sessionId);  
    sessionCounter++;    
    return (session);    
}

通過上述過程,一個新的Session就創建出來了。

關于“如何創建session對象”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

正定县| 镇江市| 绥棱县| 广平县| 伊川县| 西华县| 舟山市| 和林格尔县| 商南县| 高尔夫| 垫江县| 彭泽县| 芜湖县| 香河县| 登封市| 清苑县| 信阳市| 杭锦后旗| 璧山县| 大同市| 普格县| 沙河市| 乐安县| 湖南省| 米林县| 闻喜县| 北票市| 翁牛特旗| 贵溪市| 五大连池市| 铅山县| 竹山县| 西华县| 太湖县| 新巴尔虎右旗| 鲁山县| 集安市| 曲周县| 文山县| 社旗县| 高阳县|