贏在執(zhí)行

          這個(gè)世界上只有兩樣?xùn)|西愈分享愈多,那就是智慧與愛。

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            17 Posts :: 11 Stories :: 13 Comments :: 0 Trackbacks

          常用鏈接

          留言簿(1)

          隨筆分類(9)

          隨筆檔案(17)

          文章分類(11)

          文章檔案(11)

          AJAX專區(qū)

          JAVA專區(qū)

          LINUX專區(qū)

          XMPP專區(qū)

          YAHOO-Ext專區(qū)

          其他方面

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

              近期因工作需求探索apache + resin的多機(jī)負(fù)載分布和多個(gè)webapp統(tǒng)一認(rèn)證的實(shí)現(xiàn)方案, 期間設(shè)計(jì)多個(gè)webapp統(tǒng)一認(rèn)證的實(shí)現(xiàn)方案時(shí), 發(fā)現(xiàn)resin下通過cookie來傳遞jsessionid和通過url重寫將jsessionid放url中傳遞, 會(huì)有細(xì)微的差異.

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

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

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

              2. 以參數(shù)形式放在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

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

          二)獲取到的HttpServletSession對(duì)象

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

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

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


              1). 測(cè)試代碼如下:
              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分別是調(diào)用request.getSession(true)方法前后的request.getRequestedSessionId()值。

              在resin中運(yùn)行以上代碼,測(cè)試request.getRequestedSessionId() 不是空值而對(duì)應(yīng)jsessionid的session不存在的情況。
             
              2). 通過cookie來傳遞jsessionid的情況,測(cè)試結(jié)果如下:

                  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

                  可以發(fā)現(xiàn)以下規(guī)律:
                  1.  isNew()=true
                  2. session.getId() == jid1 == jid2
                      即新創(chuàng)建的session會(huì)使用傳遞過來的jsessionid值,即使這個(gè)jsessionid值根本沒有對(duì)應(yīng)的session存在

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

                  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地址為頁面跳轉(zhuǎn)完成后顯示在瀏覽器地址框中的頁面url)
                 
                  可以發(fā)現(xiàn)以下規(guī)律:
                  1. isNew()=true
                  2. jid1 == jid2
                      request.getRequestedSessionId()值在request.getSession(true)方法調(diào)用前后無變化
                  3. session.getId()  != jid1
                      即新創(chuàng)建的session不使用傳遞過來的jsessionid值,而是采用新值
                  4. 跳轉(zhuǎn)完成后的http地址中,使用的是session.getId(), 而不是原來通過url重寫傳遞過來的jsessionid
                      此時(shí)新的jsessionid覆蓋了舊有的jsessionid.

              4) 總結(jié)
                  在resin的實(shí)現(xiàn)中, 通過cookie來傳遞jsessionid的情況和通過url重寫將jsessionid放url中傳遞, 會(huì)有細(xì)微的差異.
                  以上測(cè)試的resin版本為3.0.26, 稍后有時(shí)間考慮測(cè)試其他版本和tomcat.

             
                  這個(gè)差異直接影響到跨webapp的多個(gè)webapp直接相互傳遞jsessionid的方式, 通過cookie傳遞jsessionid可以做到多個(gè)webapp之間在頁面跳轉(zhuǎn)時(shí)始終是一個(gè)相同的jsessionid,這種各個(gè)應(yīng)用都可以方便的獲取到自己的HttpServletSession對(duì)象. 但是如果是通過url重寫,則破壞了jsessonid的一致性, 逼迫各個(gè)webapp之間跳轉(zhuǎn)時(shí)必須用其他額外的方法來保證傳遞給對(duì)方的jsessionid的準(zhǔn)確性,因?yàn)榇藭r(shí)每個(gè)webapp的jsessionid都不一樣了,必須記住其他每個(gè)webapp的jsessionid,造成跨webapp的頁面跳轉(zhuǎn)極其復(fù)雜,難于接受.
          posted on 2008-02-01 00:24 飛雪(leo) 閱讀(450) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 海南省| 沂南县| 苗栗县| 万州区| 临潭县| 上高县| 遵义市| 克东县| 十堰市| 宾阳县| 甘肃省| 陇西县| 正镶白旗| 临沂市| 诏安县| 兴国县| 喀喇沁旗| 武义县| 通州区| 水城县| 巫山县| 兴海县| 西贡区| 平乐县| 木兰县| 仪征市| 仲巴县| 杭州市| 玛纳斯县| 托克逊县| 永修县| 盐边县| 土默特左旗| 桃园市| 尚志市| 商水县| 曲靖市| 阿拉尔市| 长治市| 登封市| 汝城县|