<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Sky's blog

    我和我追逐的夢

    常用鏈接

    統計

    其他鏈接

    友情鏈接

    最新評論

    resin的session id reuse特性(1)--發現問題

        近期因工作需求探索apache + resin的多機負載分布和多個webapp統一認證的實現方案, 期間設計多個webapp統一認證的實現方案時, 發現resin下通過cookie來傳遞jsessionid和通過url重寫將jsessionid放url中傳遞, 會有細微的差異.

        注:后來研究發現是resin提供的session id reuse特性,只是此文第一次發布時我還不知道有此特性,慚愧。

    在servlet規范中,HttpServletSession的獲取時通過調用request.getSession(boolean createnew)方法來實現,其實現機制可以簡單的理解為: 存在一個大的hashMap結構,key就是jsessionid,而valule是HttpservletSession對象。request.getSession(boolean createnew)方法通過jsessionid來獲取對應的HttpservletSession,如果不存在并且參數createnew=true,則創建一個新的HttpservletSession對象,并設置jsessionid=session.getId() ,保存到hashMap結構中。以后再傳遞這個jsessionid. (詳細的過程比較復雜,各家的實現也不盡相同,但大體的實現原理是如此。)

    關注以下幾點:
    一). 獲取jsessionid
        jsessionid的傳遞可以是以下途徑
        1. 放在cookie中
            Cookie: JSESSIONID=abcrmF3Gx-5Z-hhkgHfzr

        2. 以參數形式放在url
            http://10.3.2.35:11280/wmail/welcome.action?jsessionid=abcQNqiT4C01rg-necLBr

        3. 用form表單傳遞,通常是用隱藏域
            <input type="hidden" name="jsessionid" value="abcQNqiT4C01rg-necLBr"/>

        4. url重寫
            http://10.3.2.35:11280/jid=abcQNqiT4C01rg-necLBr/wmail/welcome.action
               或者
            http://10.3.2.35:11280/wmail/welcome.action;jsessionid=abcQNqiT4C01rg-necLBr

        如果當前還沒有jsessionid則當然就無法獲取,通常用戶第一次訪問或者登錄前就是這種情況.
       
        可以通過request.getRequestedSessionId() 方法來獲取本次http 請求的jsessonid值。

    二)獲取到的HttpServletSession對象

        如果HttpServletSession對象是已經存在的,則
        1. session.isNew()=false
        2. request.getRequestedSessionId() == jsessionid == session.getId()

        如果HttpServletSession對象是調用request.getSession(true) (簡寫的request.getSession()方法等同于request.getSession(true) )時新創建的,則有以下特征:
        1. session.isNew()=true
        2. 以后傳遞的jsessionid=session.getId()
            注意這里,如果request.getRequestedSessionId() 是空值,情況比較簡單,以后傳遞jsessionid=session.getId()就是了。
            但是如果request.getRequestedSessionId() 不是空值,通過這個值沒有獲取到已經存在的session對象,而是返回了一個新的session對象,這個時候新的session.getId()和原有的request.getRequestedSessionId() 關系如何呢?下面詳細闡述這種情況。
       

    三) request.getRequestedSessionId() 不是空值時,新的session.getId() = ?


        1). 測試代碼如下:
        HttpServletRequest request = ServletActionContext.getRequest();
        String jid1 = request.getRequestedSessionId();
        HttpSession session = request.getSession(true);
        String jid2 = request.getRequestedSessionId();

        logger.info("get HttpSession , isNew()=" + session.isNew()
                        + " getId()=" + session.getId()
                        + " and jid1=" + jid1
                        + " and jid2=" + jid2);

        其中jid1和jid2分別是調用request.getSession(true)方法前后的request.getRequestedSessionId()值。

        在resin中運行以上代碼,測試request.getRequestedSessionId() 不是空值而對應jsessionid的session不存在的情況。
       
        2). 通過cookie來傳遞jsessionid的情況,測試結果如下:

            get HttpSession, isNew()=true getId()=abcqIgQroQ2Ov9lGYcYAr and jid1=abcqIgQroQ2Ov9lGYcYAr and jid2=abcqIgQroQ2Ov9lGYcYAr

            get HttpSession, isNew()=true getId()=abcPQ3mpxKz8H-4UMdYAr and jid1=abcPQ3mpxKz8H-4UMdYAr and jid2=abcPQ3mpxKz8H-4UMdYAr

            get HttpSession, isNew()=true getId()=abcdeE3iDy_bI536tLYAr and jid1=abcdeE3iDy_bI536tLYAr and jid2=abcdeE3iDy_bI536tLYAr

            可以發現以下規律:
            1.  isNew()=true
            2. session.getId() == jid1 == jid2
                即新創建的session會使用傳遞過來的jsessionid值,即使這個jsessionid值根本沒有對應的session存在

        3)  通過url重寫,將jsessionid放url中傳遞, 測試結果如下:

            get HttpSession, isNew()=true getId()=abccw1zEC_RcN43qHMYAr and jid1=abcdUdTfKuLbge8h_LYAr and jid2=abcdUdTfKuLbge8h_LYAr
            http://10.3.2.35:11280/jid=abccw1zEC_RcN43qHMYAr/uab/contactList.action

            get HttpSession, isNew()=true getId()=abcFK7yOB1irgaYqgNYAr and jid1=abci-HpMPJU3egCB7MYAr and jid2=abci-HpMPJU3egCB7MYAr
            http://10.3.2.35:11280/jid=abcFK7yOB1irgaYqgNYAr/uab/contactList.action

            (后面的http地址為頁面跳轉完成后顯示在瀏覽器地址框中的頁面url)
           
            可以發現以下規律:
            1. isNew()=true
            2. jid1 == jid2
                request.getRequestedSessionId()值在request.getSession(true)方法調用前后無變化
            3. session.getId()  != jid1
                即新創建的session不使用傳遞過來的jsessionid值,而是采用新值
            4. 跳轉完成后的http地址中,使用的是session.getId(), 而不是原來通過url重寫傳遞過來的jsessionid
                此時新的jsessionid覆蓋了舊有的jsessionid.

        4) 總結
            在resin的實現中, 通過cookie來傳遞jsessionid的情況和通過url重寫將jsessionid放url中傳遞, 會有細微的差異.
            以上測試的resin版本為3.0.26, 稍后有時間考慮測試其他版本和tomcat.

       
            這個差異直接影響到跨webapp的多個webapp直接相互傳遞jsessionid的方式, 通過cookie傳遞jsessionid可以做到多個webapp之間在頁面跳轉時始終是一個相同的jsessionid,這種各個應用都可以方便的獲取到自己的HttpServletSession對象. 但是如果是通過url重寫,則破壞了jsessonid的一致性, 逼迫各個webapp之間跳轉時必須用其他額外的方法來保證傳遞給對方的jsessionid的準確性,因為此時每個webapp的jsessionid都不一樣了,必須記住其他每個webapp的jsessionid,造成跨webapp的頁面跳轉極其復雜,難于接受.

    posted on 2007-12-17 10:52 sky ao 閱讀(3448) 評論(3)  編輯  收藏 所屬分類: web

    評論

    # re: resin的session id reuse特性(1)--發現問題 2008-01-02 14:35 laohuidi

    good  回復  更多評論   

    # re: resin的session id reuse特性(1)--發現問題[未登錄] 2011-04-08 15:42 楊洋

    謝謝你的教導!!受益頗多!!!  回復  更多評論   

    # re: resin的session id reuse特性(1)--發現問題[未登錄] 2011-04-08 15:43 楊洋

    收益頗多  回復  更多評論   

    主站蜘蛛池模板: 免费精品国偷自产在线在线| 99视频免费播放| 国产精品冒白浆免费视频| 91亚洲性爱在线视频| 国产福利在线观看免费第一福利| 亚洲福利一区二区三区| 4虎永免费最新永久免费地址| 亚洲最大黄色网址| 亚洲一区在线免费观看| 亚洲成AV人片久久| 久久精品a一国产成人免费网站| 亚洲色精品VR一区区三区 | 中文在线免费不卡视频| 亚洲AV无码一区二区二三区软件| 国产精品白浆在线观看免费| 亚洲一区二区电影| 色婷婷7777免费视频在线观看| 中文字幕亚洲精品无码| av无码东京热亚洲男人的天堂| 久香草视频在线观看免费| 亚洲人精品午夜射精日韩| 无码精品人妻一区二区三区免费看| 亚洲精品国产免费| 日本无卡码免费一区二区三区| 一道本不卡免费视频| 亚洲AV人人澡人人爽人人夜夜| 亚洲成人在线免费观看| 亚洲熟妇成人精品一区| 亚洲人成国产精品无码| 久久国产乱子伦免费精品| 亚洲精品免费网站| 国产专区一va亚洲v天堂| 99久久综合精品免费| 国产精品亚洲精品日韩电影| 亚洲性猛交XXXX| 黄色片在线免费观看| 久久精品成人免费观看97| 亚洲高清日韩精品第一区| 四虎影在线永久免费四虎地址8848aa | 亚洲第一永久AV网站久久精品男人的天堂AV| 亚洲第一视频在线观看免费|