国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

Struts網(wǎng)站動(dòng)態(tài)導(dǎo)航系統(tǒng)設(shè)計(jì)思路探討

2019-11-18 15:11:44
字體:
供稿:網(wǎng)友

  版權(quán)聲明:本文章為學(xué)習(xí)日記網(wǎng)站(http://www.learndiary.com )版權(quán)所有,以<a >Creative Commons License</a>方式授權(quán)。歡迎轉(zhuǎn)載,但請注明文章原始出處(http://www.learndiary.com/disDiaryContentAction.do?searchDiaryID=&goalID=1255&naviStr=a10a2167 )。

提綱:
  一、背境;
  二、需求分析:
    1、學(xué)習(xí)日記網(wǎng)站的主要功能頁面結(jié)構(gòu);
    2、需要進(jìn)行動(dòng)態(tài)導(dǎo)航的主要模塊;
    3、需求的提出:
      1)、層次導(dǎo)航的需求;
      2)、同一列表中帖子間的導(dǎo)航(即上一條,下一條類似的導(dǎo)航);
      3)、父帖與子帖列表的雙向?qū)Ш剑?br />  三、具體實(shí)現(xiàn)過程:
    1、層次導(dǎo)航的實(shí)現(xiàn)過程:
      1)列出導(dǎo)航功能需求列表,看都有哪些導(dǎo)航路徑;
      2)分析定位特定類型的頁面所需的參數(shù);
      3)確定層次導(dǎo)航的實(shí)現(xiàn)方法;
      4)進(jìn)行層次導(dǎo)航系統(tǒng)的設(shè)計(jì):
        (1)、進(jìn)行頁面節(jié)點(diǎn)導(dǎo)航封裝字符串格式的設(shè)計(jì);
        (2)、頁面完整導(dǎo)航字符串的設(shè)計(jì);
        (3)、將封裝的導(dǎo)航字符串還原為顯示在頁面上的URL地址導(dǎo)航條;
        (4)、在頁面上顯示層次導(dǎo)航的URL字符串;
    2、同一列表中帖子間的導(dǎo)航(即上一條,下一條類似的導(dǎo)航)的實(shí)現(xiàn)過程:
      1)列出導(dǎo)航需求列表;
      2)分析實(shí)現(xiàn)上一條、下一條導(dǎo)航所需的參數(shù);
      3)確定實(shí)現(xiàn)上一條、下一條導(dǎo)航的實(shí)現(xiàn)方法;
      4)進(jìn)行上一條、下一條導(dǎo)航的設(shè)計(jì):
        (1)、根據(jù)層次導(dǎo)航的導(dǎo)航字符串確定上一條、下一條導(dǎo)航所在的層次導(dǎo)航位置;
        (2)、確定在哪幾個(gè)Struts的Action中需要處理上一條、下一條導(dǎo)航;
        (3)、在頁面上顯示上一條、下一條導(dǎo)航的URL字符串;
    3、父帖與子帖列表的雙向?qū)Ш降膶?shí)現(xiàn)過程:
      1)列出導(dǎo)航需求列表;
      2)分析實(shí)現(xiàn)雙向?qū)Ш剿璧膮?shù);
      3)確定實(shí)現(xiàn)方法;
      4)進(jìn)行雙向?qū)Ш降脑O(shè)計(jì):
        (1)、確定在哪幾個(gè)Struts的Action中需要處理雙向?qū)Ш剑?br />        (2)、在頁面上顯示雙向?qū)Ш降腢RL字符串;
  四、總結(jié):
    1、心得;
    2、優(yōu)點(diǎn);
    3、缺點(diǎn);
    4、愿望;
  五、聯(lián)系方式;
  六、附件(附學(xué)習(xí)日記V0.9.0.4和學(xué)習(xí)日記系統(tǒng)ArgoUML建模(學(xué)習(xí)日記V0.9.0.4反向工程類圖) )。

  要害詞:學(xué)習(xí)日記 Struts 動(dòng)態(tài)導(dǎo)航 學(xué)習(xí)日記動(dòng)態(tài)導(dǎo)航技術(shù)(簡稱:LDDN技術(shù) ) 學(xué)習(xí)日記開發(fā)小組(簡稱:LDDG )

××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

           <font size="+2"><b>正文</b></font>

  一、背境:
  學(xué)習(xí)日記(http://www.learndiary.com )網(wǎng)站是采用Struts框架的開源項(xiàng)目learndiary(http://develop.learndiary.com )的實(shí)際運(yùn)行示范站點(diǎn)。目前由學(xué)習(xí)日記開發(fā)小組進(jìn)行開發(fā),致力于以java技術(shù)構(gòu)建一個(gè)普遍適用的開源網(wǎng)絡(luò)學(xué)習(xí)交流平臺。為了改善用戶的瀏覽體驗(yàn),故提出導(dǎo)航系統(tǒng)的改善計(jì)劃。已經(jīng)包含了這個(gè)導(dǎo)航系統(tǒng)的的最新版本為learndiaryV0.9.0.4。本文所提到的程序均可以在本站的下載菜單中獲取:http://www.learndiary.com/download/download.Html 。本文希望起到一個(gè)拋磚引玉的作用,引發(fā)一場關(guān)于java技術(shù)構(gòu)建的web系統(tǒng)的導(dǎo)航系統(tǒng)設(shè)計(jì)的討論。

  二、基本思路:
  1、學(xué)習(xí)日記網(wǎng)站的主要功能頁面結(jié)構(gòu):
  核心為:目標(biāo)列表-》目標(biāo)內(nèi)容及評論-》目標(biāo)下的日記列表-》日記內(nèi)容及評論
  (示意圖:http://www.learndiary.com/pictures/navigationdesign/pagesStrUCture.gif )

  2、需要進(jìn)行動(dòng)態(tài)導(dǎo)航的主要模塊:
  需要進(jìn)行動(dòng)態(tài)導(dǎo)航的主要模塊有3個(gè),見學(xué)習(xí)日記網(wǎng)站的菜單欄:
    1)、所有目標(biāo):http://www.learndiary.com/indexAction.do?pageNum=1&naviStr=a10 (顯示學(xué)友提出的所有學(xué)習(xí)目標(biāo)列表 )
    2)、檢索:http://www.learndiary.com/toSearchAction.do?naviStr=a10ac0 (檢索本站的所有學(xué)習(xí)目標(biāo)和學(xué)習(xí)日記 )
    3)、您的目標(biāo):http://www.learndiary.com/PRocessGoalAction.do?currentGoalState=1&pageNum=1&naviStr=a10a60 (學(xué)友自己的學(xué)習(xí)目標(biāo)歸類:包括:進(jìn)行中的目標(biāo)、退出的目標(biāo)、已完成的目標(biāo) )

  3、需求的提出:
    1)、層次導(dǎo)航的需求:
    我們想建成一個(gè)導(dǎo)航系統(tǒng),它可以跟蹤用戶在系統(tǒng)中瀏覽頁面的過程,每瀏覽到一個(gè)新的頁面,就在導(dǎo)航條中加入這個(gè)頁面的URL,于是,當(dāng)用戶瀏覽到別的頁面,可以點(diǎn)擊返回系統(tǒng)導(dǎo)航條中的前面瀏覽過的頁面;當(dāng)瀏覽一個(gè)頁面是與導(dǎo)航條中已經(jīng)存在的頁面類型一致時(shí),就截去導(dǎo)航條中此類型頁面后面的導(dǎo)航URL。
  征對這個(gè)需求,我大概看了一下動(dòng)網(wǎng)的實(shí)現(xiàn)方式和phpWind論壇的實(shí)現(xiàn)方式,他們用的導(dǎo)航基本上是靜態(tài)的,也就是說,一種頁面上的導(dǎo)航條是固定的,例如:顯示一條帖子的內(nèi)容,他們的方式是:論壇首頁-》論壇版塊-》主題內(nèi)容。
  而我們的需求是,例如:顯示一篇日記的內(nèi)容:
  在所有目標(biāo)模塊中,導(dǎo)航條為:所有目標(biāo)>>日記列表>>日記內(nèi)容;(圖例:http://www.learndiary.com/pictures/navigationdesign/disDiaryInAllGoal.gif )
  在檢索模塊中,導(dǎo)航條為:所有目標(biāo)>>檢索>>檢索日記列表>>日記內(nèi)容;(圖例:http://www.learndiary.com/pictures/navigationdesign/disDiaryInSearch.gif )
  在您的目標(biāo)中,導(dǎo)航條為:所有目標(biāo)>>我進(jìn)行中的目標(biāo)>>本目標(biāo)我的日記列表>>日記內(nèi)容;(圖例:http://www.learndiary.com/pictures/navigationdesign/disDiaryInMine.gif )
    2)、同一列表中帖子間的導(dǎo)航(即上一條,下一條類似的導(dǎo)航 ):
    另外,除了上面層次導(dǎo)航的需求,同一列表中帖子間的導(dǎo)航(即上一條,下一條類似的導(dǎo)航 ),我們也想在網(wǎng)上一般的導(dǎo)航系統(tǒng)的基礎(chǔ)有所改良。例如:在一般的導(dǎo)航系統(tǒng)中,假如你在檢索結(jié)果的列表中點(diǎn)擊查看一篇帖子,然后,你再點(diǎn)擊這篇帖子的上一條和下一條鏈接,新點(diǎn)開的頁面不是檢索結(jié)果列表中的上一篇或下一篇帖子,而是這條帖子所有的版塊的上一條和下一條帖子。
  我們需要在檢索結(jié)果列表中,點(diǎn)擊檢索到的一篇日記中的“上一條”和“下一條”鏈接時(shí),顯示的是檢索結(jié)果列表中本日記的上一條和下一條日記。
  例如,我們以“中文顯示”為要害字檢索日記得到一個(gè)檢索結(jié)果列表:(圖例:http://www.learndiary.com/pictures/navigationdesign/diarySearchList.gif )
  當(dāng)我點(diǎn)擊查看“解決:jsp頁面中文顯示問題”這篇日記中的下一條鏈接時(shí),我們需要打開檢索結(jié)果列表的下一篇日記:“問題:jsp中文顯示,<c:set>的值可否是對象?me ”:(圖例:http://www.learndiary.com/pictures/navigationdesign/nextDiaryInSearch.gif ),而不是“解決:jsp頁面中文顯示問題”這篇日記所在的目標(biāo)中的下一篇日記。
  在“您的目標(biāo)”這個(gè)模塊中的“上一條”和“下一條”的導(dǎo)航同樣存在在檢索頁面中點(diǎn)擊“上一條”和“下一條”鏈接的問題。
    3)、父帖與子帖列表的雙向?qū)Ш剑?br />    學(xué)習(xí)日記征對自身的功能結(jié)構(gòu)特點(diǎn),還需要實(shí)現(xiàn):“目標(biāo)<──>目標(biāo)下的所有日記列表”的雙向?qū)Ш胶汀澳繕?biāo)<──>目標(biāo)下我的日記列表”的雙向?qū)Ш剑猴@示目標(biāo)內(nèi)容(圖例:http://www.learndiary.com/pictures/navigationdesign/aGoalContent.gif ),您可以看到頁面右邊中上有兩個(gè)鏈接分別是:“查看所有日記”和“查看我的日記”,點(diǎn)擊“查看所有日記”鏈接出現(xiàn)的是頁面(圖例:http://www.learndiary.com/pictures/navigationdesign/allDiariesListOfGoal.gif ),點(diǎn)擊“查看我的日記”鏈接出現(xiàn)的是頁面(圖例:http://www.learndiary.com/pictures/navigationdesign/myDiariesListOfGoal.gif );后面這兩個(gè)頁面的右中上部又都有到日記所在的目標(biāo)中的鏈接:“查看目標(biāo)內(nèi)容”。
  以上總結(jié)了學(xué)習(xí)日記需要實(shí)現(xiàn)的導(dǎo)航系統(tǒng)的三個(gè)方面的需求,征對這個(gè)需求,我看了一些論壇,均沒有現(xiàn)存的東西可以參考,于是,我們決定探索一種能夠?qū)崿F(xiàn)上面動(dòng)態(tài)導(dǎo)航需求的方法。因?yàn)槲覀儗?shí)現(xiàn)的導(dǎo)航系統(tǒng)是動(dòng)態(tài)變化的,故把這種實(shí)現(xiàn)的方法稱之為“學(xué)習(xí)日記動(dòng)態(tài)導(dǎo)航技術(shù)”(簡稱:LDDN技術(shù) )。下面把我們的具體設(shè)計(jì)過程總結(jié)一下。

  三、具體實(shí)現(xiàn)過程:
  具體的設(shè)計(jì)分析過程我已經(jīng)在進(jìn)行的過程中記錄在日記中了,所以,假如你要具體的了解我的分析設(shè)計(jì)過程的話,可以去看這兩篇日記:
  第一篇日記:“提高學(xué)習(xí)日記導(dǎo)航能力的思路”(http://www.learndiary.com/disDiaryContentAction.do?searchDiaryID=&goalID=1128&naviStr=a10a2506ah1167 ),主要記錄的是我在對層次導(dǎo)航部分的分析設(shè)計(jì)過程;
  第二篇日記:“分析學(xué)習(xí)日記橫向?qū)Ш郊伴_幾個(gè)窗口的思路”(http://www.learndiary.com/disDiaryContentAction.do?searchDiaryID=&goalID=1167&naviStr=a10a2506ah1128 ),主要記錄的是我在對“上一條”和“下一條”導(dǎo)航部分的分析與設(shè)計(jì)過程。
  當(dāng)然,細(xì)節(jié)總是太煩瑣和令人不愉快的,我把大概的設(shè)計(jì)過程總結(jié)如下:

  1、層次導(dǎo)航的實(shí)現(xiàn)過程:
  1)列出導(dǎo)航功能需求列表,看都有哪些導(dǎo)航路徑,例如:
    (5)所有目標(biāo)列表->相關(guān)日記列表->顯示日記內(nèi)容->編輯評論;
    (14)所有目標(biāo)列表->進(jìn)行中的目標(biāo)列表->您的日記列表->顯示日記內(nèi)容->編輯評論;
    (21)所有目標(biāo)列表->檢索頁面->搜索結(jié)果日記列表->相關(guān)日記列表->顯示日記內(nèi)容->撰寫評論;
  全部列表請見我上面提到的第一篇日記中的“一、學(xué)習(xí)日記導(dǎo)航路徑列舉:”(您可以在頁面中搜索位置,前后的雙引號除外,下同 )。

  2)分析定位特定類型的頁面所需的參數(shù)(這樣,就可以根據(jù)頁面類型和參數(shù)唯一的確定一個(gè)頁面了 ):
  經(jīng)過分析,唯一定位一個(gè)頁面所需要的參數(shù)變?yōu)椋?
    1》頁面類型;
    2》參數(shù)ID;
  其中參數(shù)ID分為下面幾種情況:
    1》列表:需要列表的parentID;
    2》單個(gè)條目:需要它的ID;
    3》用戶的進(jìn)行、完成等目標(biāo)列表:什么都不需要,用戶ID在session中;
    4》用戶的進(jìn)行、完成等目標(biāo)的用戶日記列表;目標(biāo)ID,所需的用戶ID在Session中;
    5》搜索列表:什么都不需要,因?yàn)樗阉鳁l件字符串已保留在全局Session中了;
  具體的分析過程請見我上面提到的第一篇日記中的“(2 )、如何唯一的定位一個(gè)特定的頁面呢? ”

  3)確定層次導(dǎo)航的實(shí)現(xiàn)方法:
  當(dāng)點(diǎn)擊一個(gè)新的頁面時(shí),就把定位這個(gè)頁面所需的參數(shù)加入到層次導(dǎo)航的參數(shù)鏈表中(鏈表的一個(gè)節(jié)點(diǎn)儲存的是一個(gè)新的頁面的定位參數(shù) ),這時(shí)鏈表變長;當(dāng)點(diǎn)擊一個(gè)在鏈表中已經(jīng)存在這種類型的頁面(例如:顯示一篇日記的內(nèi)容的頁面 )時(shí),就把在導(dǎo)航鏈表中這個(gè)節(jié)點(diǎn)及后面的節(jié)點(diǎn)刪除,再加上這個(gè)點(diǎn)擊的頁面的定位參數(shù)。
  實(shí)現(xiàn)這種層次導(dǎo)航的需求有兩種方法:
    (1)、為每條導(dǎo)航路徑在session中設(shè)置一個(gè)層次導(dǎo)航所需的屬性,在這條路徑上導(dǎo)航鏈表的增長和縮短信息就由這個(gè)屬性來維持;
    (2)、把這個(gè)鏈表封裝成字符串,這個(gè)字符串在訪問不同的頁面時(shí),會(huì)根據(jù)上面的思路不斷增長和縮短。把這個(gè)封裝的字符串連同用戶新請求的頁面的定位參數(shù)節(jié)點(diǎn)字符串一起傳給請求這個(gè)頁面前的Struts的action,形成新的頁面上導(dǎo)航條所需的編碼字符串,然后把這個(gè)編碼字符串保存在request中,供請求的頁面中的下一個(gè)鏈接使用;并同時(shí)由action把這個(gè)形成的編碼導(dǎo)航字符串解碼處理成用戶請求的頁面上需要的導(dǎo)航字符串。
  經(jīng)過分析,我決定采用第(2 )種方法來實(shí)現(xiàn)層次導(dǎo)航。
  具體的分析過程請見我上面提到的第一篇日記中的“我知道有2種方法可以解決這個(gè)問題 ”。

  4 )進(jìn)行層次導(dǎo)航系統(tǒng)的設(shè)計(jì):
    (1)、進(jìn)行頁面節(jié)點(diǎn)導(dǎo)航封裝字符串格式的設(shè)計(jì):
    分隔符(用'a'作分隔符 )+頁面節(jié)點(diǎn)類型(用一位字符代表,封裝成一個(gè)頁面類型常量類,用字符1-9,英文字符b-z和A-Z表示 )+頁面參數(shù)ID(如顯示目標(biāo)的日記列表所需的目標(biāo)ID,顯示日記內(nèi)容所需的日記ID )。如顯示一篇日記的頁面類型常量為字符:‘h’,那么,顯示“解決:jsp頁面中文顯示問題”這篇日記內(nèi)容(ID為292 )這一頁面的封裝字符串為:ah292;
    (2)、頁面完整導(dǎo)航字符串的設(shè)計(jì):
    在下面的討論中會(huì)用到的相關(guān)源文件:
  負(fù)責(zé)封裝學(xué)習(xí)日記所需導(dǎo)航的頁面的類型常量(/WEB-INF/src/com/learndiary/website/PageTypeConsts.java );
  負(fù)責(zé)導(dǎo)航字符串封裝的方法(/WEB-INF/src/com/learndiary/website/util/Pager.java中的public static String encodeNaviStr(String naviStr, char toPageType, String parameter) );

    當(dāng)用戶提出一個(gè)新的頁面請求,把當(dāng)前頁面中的完整的導(dǎo)航封裝字符串和新的頁面的類型和新請求頁面的參數(shù)ID傳給處理新頁面顯示前的Struts中的Action中,由Action調(diào)用一個(gè)方法,負(fù)責(zé)把這些參數(shù)組裝成下一新頁面所需的導(dǎo)航字符串。如:當(dāng)前正顯示的頁面是“系統(tǒng)導(dǎo)航:所有目標(biāo)>>我進(jìn)行中的目標(biāo)>>目標(biāo):一起學(xué)習(xí)Struts(MVC)我的日記列表”中的“目標(biāo):一起學(xué)習(xí)Struts(MVC)我的日記列表”(圖例:http://www.learndiary.com/pictures/navigationdesign/myDiariesList.gif ),你可以看到當(dāng)點(diǎn)擊顯示日記“解決:jsp頁面中文顯示問題 (0篇) ”的URL中的導(dǎo)航字符串為:“naviStr=a10a60a0167”(圖例中左下方紅圈中 ),把這個(gè)字符串和請求的顯示日記的頁面類型(日記為:‘h’ )和顯示這篇日記所需的ID(292 )傳給顯示日記內(nèi)容前的Action中(disDiaryContentAction.do,源文件為:/WEB-INF/src/com/learndiary/website/action/disgoal/DisGoalContentAction.java ),由負(fù)責(zé)導(dǎo)航字符串封裝的方法(源文件為:/WEB-INF/src/com/learndiary/website/util/Pager.java中的public static String encodeNaviStr(String naviStr, char toPageType, String parameter) )進(jìn)行處理,處理流程為:以顯示日記這個(gè)頁面的類型ID為‘h’搜索已有導(dǎo)航字符串,沒有相同的頁面,于是就把這個(gè)頁面導(dǎo)航字符串節(jié)點(diǎn)(ah292 )加到完整的導(dǎo)航字符串(a10a60a0167)后面得到新的導(dǎo)航字符串(a10a60a0167ah292 ),見例圖:(http://www.learndiary.com/pictures/navigationdesign/disDiaryInMine2.gif ),你可以看到當(dāng)點(diǎn)擊“日記:解決:jsp頁面中文顯示問題”這篇日記中的“我要評論”的URL中的導(dǎo)航字符串為:“naviStr=a10a60a0167ah292”(圖例中左下方紅圈中 );
  當(dāng)點(diǎn)擊當(dāng)前頁面中的回到上級導(dǎo)航節(jié)點(diǎn)的鏈接時(shí),如:“系統(tǒng)導(dǎo)航:所有目標(biāo)>>我進(jìn)行中的目標(biāo)>>目標(biāo):一起學(xué)習(xí)Struts(MVC)我的日記列表”中的“我進(jìn)行中的目標(biāo)”,這時(shí)顯示“我進(jìn)行中的目標(biāo)”頁面的類型代碼是‘6’,參數(shù)ID是“0”,那么以新頁面的節(jié)點(diǎn)字符串(a60 )的類型代碼‘6’搜索已有導(dǎo)航字符串,已經(jīng)存在相同的類型代碼,于是,就把導(dǎo)航字符串中這個(gè)節(jié)點(diǎn)和后面的所有節(jié)點(diǎn)刪除得到字符串“a10”,再加上新頁面的節(jié)點(diǎn)字符串為“a60”,得到顯示“我進(jìn)行中的目標(biāo)”頁面的導(dǎo)航字符串為“a10a60”,見例圖:(http://www.learndiary.com/pictures/navigationdesign/myProcessGoals.gif ),你可以看到當(dāng)點(diǎn)擊“一起學(xué)習(xí)Struts(MVC) (19篇)”這篇目標(biāo)的URL中的導(dǎo)航字符串為:“naviStr=a10a60”(圖例中左下方紅圈中 );
  具體分析設(shè)計(jì)過程我上面提到的第一篇日記中的“2、設(shè)計(jì)中用到的方法: ”;
    (3)、將封裝的導(dǎo)航字符串還原為顯示在頁面上的URL地址導(dǎo)航條:
    同樣用上面的顯示在“我進(jìn)行中的目標(biāo)”中目標(biāo)“一起學(xué)習(xí)Struts(MVC)我的日記列表”中的日記“解決:jsp頁面中文顯示問題”來進(jìn)行說明,也就是說:如何把導(dǎo)航封裝字符串“a10a60a0167ah292”轉(zhuǎn)換成字符串“系統(tǒng)導(dǎo)航:<a href="/learndiary/indexAction.do?searchDiaryID=&pageNum=1&naviStr=a10a60a0167ah292">所有目標(biāo)</a>>><a href="/learndiary/processGoalAction.do?searchDiaryID=¤tGoalState=1&pageNum=1&naviStr=a10a60">我進(jìn)行中的目標(biāo)</a>>><a href="/learndiary/myDiaryAction.do?searchDiaryID=&pageNum=1&goalID=167&naviStr=a10a60a0167ah292">目標(biāo):一起學(xué)習(xí)Struts(MVC)我的日記列表</a>>>日記:解決:jsp頁面中文顯示問題<p>”,
使它在頁面上顯示導(dǎo)航條為“系統(tǒng)導(dǎo)航:所有目標(biāo)>>我進(jìn)行中的目標(biāo)>>目標(biāo):一起學(xué)習(xí)Struts(MVC)我的日記列表>>日記:解決:jsp頁面中文顯示問題”(見圖例:http://www.learndiary.com/pictures/navigationdesign/disDiaryInMine2.gif )?
  解決這個(gè)問題我用兩步走的方法:
  <1>、用一個(gè)方法可以把每一個(gè)導(dǎo)航節(jié)點(diǎn)的封裝字符串轉(zhuǎn)換為導(dǎo)航URL字符串。主要是根據(jù)需要顯示的頁面類型和參數(shù)ID來進(jìn)行轉(zhuǎn)換,實(shí)現(xiàn)過程比較簡單,請查看源文件中負(fù)責(zé)解封導(dǎo)航節(jié)點(diǎn)封裝字符串的方法(/WEB-INF/src/com/learndiary/website/util/Pager.java中的public static String decodeNodeStr(String naviStr, String nodeNaviStr, HttpServletRequest request, boolean ifLast) throws Exception );
  <2>、把每個(gè)節(jié)點(diǎn)封裝的字符串聯(lián)接在一起,形成完成的頁面層次導(dǎo)航所需的URL字符串。根據(jù)慣例,當(dāng)前(也就是最后一個(gè)節(jié)點(diǎn)的導(dǎo)航URL灰化,無鏈接 )。具體實(shí)現(xiàn)請查看源文件中負(fù)責(zé)解封整個(gè)導(dǎo)航封裝字符串的方法(/WEB-INF/src/com/learndiary/website/util/Pager.java中的public static String decodeNaviStr(String naviStr, HttpServletRequest request) throws Exception );
  具體的分析設(shè)計(jì)過程請見我上面提到的第一篇日記中的“把封裝的字符串轉(zhuǎn)化為下一個(gè)頁面顯示導(dǎo)航條所需要的字符串”。

    (4)、在頁面上顯示層次導(dǎo)航的URL字符串
    在需要層次導(dǎo)航的頁面上,把從request中獲得的屬性“navigation”顯示在頁面的左上部,并把從request中獲得的相應(yīng)的封裝導(dǎo)航字符串naviStr作為參數(shù)附在每一個(gè)URL的后面就行了。
  至此,學(xué)習(xí)動(dòng)態(tài)導(dǎo)航系統(tǒng)中的層次導(dǎo)航部分已經(jīng)設(shè)計(jì)完成,下面繼續(xù)進(jìn)行顯示“上一條”和“下一條”的水平導(dǎo)航部分的探索。

  2、同一列表中帖子間的導(dǎo)航(即上一條,下一條類似的導(dǎo)航 )的實(shí)現(xiàn)過程:
    1)列出導(dǎo)航需求列表:
      (1)、在所有目標(biāo)列表中:
        1>目標(biāo)內(nèi)容;
        2>目標(biāo)的日記列表(上一條:在這里即上一目標(biāo)的日記列表);
        3>日記列表中的日記內(nèi)容;
      (2)、在檢索結(jié)果頁面中:
        1>檢索目標(biāo)列表:
          <1>目標(biāo)內(nèi)容;
          <2>目標(biāo)的日記列表;
          <3>日記列表中的日記內(nèi)容;  
        2>檢索日記列表:
          <1>日記內(nèi)容;
          <2>所在目標(biāo)的日記列表中的日記內(nèi)容; 
      (3)、您的進(jìn)行中的目標(biāo)列表:
        1>目標(biāo)內(nèi)容;
        2>目標(biāo)的全部日記列表;
        3>目標(biāo)的我的日記列表;
        4>目標(biāo)的全部日記列表中的日記;
        5>目標(biāo)的我的日記列表中的日記;

    2)分析實(shí)現(xiàn)上一條、下一條導(dǎo)航所需的參數(shù):
      因?yàn)槭菍?shí)現(xiàn)同一列表中的同一級別的帖子之間的導(dǎo)航,所以只需要得到需要導(dǎo)航的條目的ID就行了,其它所有參數(shù)都不必改變。

    3)確定實(shí)現(xiàn)上一條、下一條導(dǎo)航的實(shí)現(xiàn)方法:
      現(xiàn)在的問題是:如何根據(jù)當(dāng)前條目的ID,得到上一條目和下一條目的ID呢?
    答案是:條目的列表,條目在列表中的排序方式,當(dāng)前條目的ID。為了在查詢結(jié)果集中得到當(dāng)前條目的前后條目的ID,可以有下面的方法:
      (1)在一個(gè)直接操縱數(shù)據(jù)庫的方法中從查詢結(jié)果集中取出每個(gè)ID(整型)后,保存在數(shù)組中,馬上關(guān)閉數(shù)據(jù)庫連接,減少數(shù)據(jù)庫連接開銷。然后在同個(gè)方法中取得前面、當(dāng)前、后面記錄的ID,只返回這3個(gè)元素的數(shù)組給Pager類(負(fù)責(zé)產(chǎn)生頁面導(dǎo)航所需要的URL字符串的工具類)處理,這樣,可以保證每條數(shù)據(jù)都是最新的,但是要不停的開啟和關(guān)閉數(shù)據(jù)庫連接;
      (2)把查詢結(jié)果產(chǎn)生的數(shù)組全部存在session中,Pager在session中取數(shù)據(jù)。這樣,可以減少數(shù)據(jù)庫的查詢,但是存在兩個(gè)問題,那個(gè)比較長的數(shù)組在session中始終占用內(nèi)存,還有,取出的數(shù)據(jù)的排序關(guān)系可能是過期的(這時(shí),有人往數(shù)據(jù)庫中增加或修改了數(shù)據(jù))。
  我覺得第一種方法可以減輕對網(wǎng)站虛擬主機(jī)資源的壓力,決定采用第一種方法。
  另外,在直接操縱數(shù)據(jù)庫產(chǎn)生的結(jié)果集中查詢鄰近的ID會(huì)出現(xiàn)幾種結(jié)果呢?
  這里用“-1”表示沒有相應(yīng)的帖子。
  1>在用戶查看帖子期間,這篇帖子被刪除了,結(jié)果返回:{-1,-1,-1};
  2>只有一篇符合要求的帖子,結(jié)果返回:{-1,當(dāng)前帖子ID,-1};
  3>當(dāng)前帖子是第一篇帖子,結(jié)果返回:{-1,當(dāng)前帖子ID,下一條帖子ID};
  4>當(dāng)前帖子是最后一篇帖子,結(jié)果返回:{上一篇帖子ID,當(dāng)前帖子ID,-1};
  5>當(dāng)前帖子前后都有帖子,結(jié)果返回:{上一篇帖子ID,當(dāng)前帖子ID,上一篇帖子ID};
  現(xiàn)在,就可以把這個(gè)含有前一條、當(dāng)前、后一條帖子ID的整型數(shù)組傳給Pager類中的產(chǎn)生上一條、下一條導(dǎo)航URL字符串的相應(yīng)方法進(jìn)行處理了。
  下面是上一條、下一條導(dǎo)航的具體設(shè)計(jì)。

    4)進(jìn)行上一條、下一條導(dǎo)航的設(shè)計(jì):
      (1)、根據(jù)層次導(dǎo)航的導(dǎo)航字符串確定上一條、下一條導(dǎo)航所在的層次導(dǎo)航位置:
      進(jìn)行上一條、下一條的導(dǎo)航需要知道被導(dǎo)航的帖子所在的層次導(dǎo)航的位置。例如:顯示一篇日記的內(nèi)容:
  在所有目標(biāo)模塊中,導(dǎo)航條為:所有目標(biāo)-》日記列表-》日記內(nèi)容;(圖例:http://www.learndiary.com/pictures/navigationdesign/disDiaryInAllGoal.gif )(路徑1)
  在檢索模塊中,導(dǎo)航條為:所有目標(biāo)>>檢索>>檢索日記列表>>日記內(nèi)容;(圖例:http://www.learndiary.com/pictures/navigationdesign/disDiaryInSearch.gif ) (路徑2)
  在您的目標(biāo)中,導(dǎo)航條為:所有目標(biāo)>>我進(jìn)行中的目標(biāo)>>本目標(biāo)我的日記列表>>日記內(nèi)容;(圖例:http://www.learndiary.com/pictures/navigationdesign/disDiaryInMine.gif ) (路徑3)
  在上一條、下一條的導(dǎo)航中,層次導(dǎo)航條除了上一條目和下一條目內(nèi)容的改變,其余是不會(huì)變的;而且,要得到當(dāng)前條目的前后條目的ID,在不同的層次導(dǎo)航中是不同的。例如:在上面的路徑1中,得到日記列表的查詢條件是本目標(biāo)下的所有日記;在路徑2中,得到日記列表的查詢條件是檢索頁面的條件組合;在路徑3中,得到日記列表的查詢條件是本目標(biāo)下的用戶的所有日記。而且,在學(xué)習(xí)日記的設(shè)計(jì)中,這三種情況的排序方式是分開的,可以由用戶在瀏覽時(shí)自選的。
  為了得到不同層次導(dǎo)航下的上一條、下一條URL導(dǎo)航字符串,我在頁面導(dǎo)航URL字符串產(chǎn)生工具類Pager((/WEB-INF/src/com/learndiary/website/util/Pager.java)中用了3個(gè)重載的、用于產(chǎn)生上一條、下一條導(dǎo)航URL字符串的方法來征對不同的三種情況(與前面說的3種路徑不是一一對應(yīng)的),分別是:
  1>、(包括對這一路徑下的目標(biāo)列表中目標(biāo)的瀏覽和目標(biāo)的日記列表的瀏覽,和檢索目標(biāo)列表中目標(biāo)的瀏覽,和檢索日記列表中日記的瀏覽):public static String getPreNextNaviStr( char toPageType, String url, HttpServletRequest request, String naviStr, int currentID, String condition,int orderType, int direction) throws Exception。輸入?yún)?shù)是:toPageType-請求的頁面類型,url-請求的頁面的“/***Action.do”路徑,request-請求對象,naviStr-當(dāng)前頁面的導(dǎo)航封裝字符串,currentID-當(dāng)前條目的ID,condition-查詢的where子句,orderType-排序類型,direction-排序方向。為了分離數(shù)據(jù)庫訪問的代碼,在這個(gè)方法中調(diào)用了一個(gè)直接訪問數(shù)據(jù)庫的類(/WEB-INF/src/com/learndiary/website/db/PageDB.java)中的方法(public int[] getAdjacentIDs(String tableName, int currentID, String condition, int orderType, int direction) throws Exception )來得到含有前一條、當(dāng)前、后一條帖子ID的數(shù)組;
  2>、(包括對檢索日記列表的日記所在目標(biāo)、日記所在目標(biāo)下的日記列表的瀏覽):public static String getPreNextNaviStr(String url, HttpServletRequest request, String naviStr, int searchDiaryID, String condition,int orderType, int direction) throws Exception。輸入?yún)?shù)是:url-請求的頁面的“/***Action.do”路徑,request-請求對象,naviStr-當(dāng)前頁面的導(dǎo)航封裝字符串,searchDiaryID-搜索日記列表中當(dāng)前日記的ID,condition-查詢的where子句,orderType-排序類型,direction-排序方向。為了分離數(shù)據(jù)庫訪問的代碼,在這個(gè)方法中調(diào)用了一個(gè)直接訪問數(shù)據(jù)庫的類(/WEB-INF/src/com/learndiary/website/db/PageDB.java)中的方法(public int[] getAdjacentIDs(String tableName, int currentID, String condition, int orderType, int direction) throws Exception )來得到含有前一條、當(dāng)前、后一條帖子ID的數(shù)組;
  3>、(包括對進(jìn)行中的目標(biāo)、退出的目標(biāo)、完成的目標(biāo)列表中目標(biāo)的瀏覽):public static String getPreNextNaviStr(String url, HttpServletRequest request, String naviStr, int userID, int currentID, int myGoalTypeFlag, int orderType, int direction) throws Exception。輸入?yún)?shù)是:url-請求的頁面的“/***Action.do”路徑,request-請求對象,naviStr-當(dāng)前頁面的導(dǎo)航封裝字符串,userID-當(dāng)前用戶ID,currentID-當(dāng)前條目的ID,myGoalTypeFlag-用戶目標(biāo)的類型(進(jìn)行、退出、或者完成),orderType-排序類型,direction-排序方向。為了分離數(shù)據(jù)庫訪問的代碼,在這個(gè)方法中調(diào)用了一個(gè)直接訪問數(shù)據(jù)庫的類(/WEB-INF/src/com/learndiary/website/db/PageDB.java)中的方法(public int[] getAdjacentIDs(int userID,int currentID, int myGoalTypeFlag, int orderType, int direction) throws Exception)來得到含有前一條、當(dāng)前、后一條帖子ID的數(shù)組;
  現(xiàn)在的問題是怎么樣來區(qū)別上面1>、2>、3>中列出的各種情況,并調(diào)用對應(yīng)的“getPreNextNaviStr”方法來產(chǎn)生正確的上一條、下一條的URL導(dǎo)航字符串呢?
  我的答案是根據(jù)當(dāng)前頁面的封裝導(dǎo)航字符串來確定,我通過分析上面1>、2>、3>中列出的各種情況的導(dǎo)航字符串的特征碼,然后在程序中通過檢索特征碼來確定當(dāng)前頁面的層次導(dǎo)航位置(對應(yīng)于上面不同的幾種情況),這是一個(gè)煩瑣的過程,這里僅列舉一二:
  例如:在檢索目標(biāo)的列表中的目標(biāo)頁面中的封裝導(dǎo)航串一定會(huì)含有“ae”兩個(gè)字符,且帖子類型為“目標(biāo)”;在檢索日記的列表中的日記頁面中的封裝導(dǎo)航串一定會(huì)含有“ad”兩個(gè)字符,且帖子類型為“日記”。

      (2)、確定在哪幾個(gè)Struts的Action中需要處理上一條、下一條導(dǎo)航:
      1)、首先,需要導(dǎo)航的地方有三種情況:
        1>、目標(biāo)內(nèi)容
        2>、日記內(nèi)容
        3>、目標(biāo)的日記列表
      2)、
        1>、1)的1>和2>需要放在DisGoalContentAction.java(/WEB-INF/src/com/learndiary/website/action/disgoal/DisGoalContentAction.java)中處理;
        2>、1)的3>需要分在幾個(gè)地方處理,分別是:
          1>檢索目標(biāo)的日記列表,所有目標(biāo)的日記列表,進(jìn)行、完成、退出的日記列表:在DiaryAction.java(/WEB-INF/src/com/learndiary/website/action/disdiary/DiaryAction.java)中處理;
          2>進(jìn)行、完成、退出的我的日記列表:在MyDiaryAction.java(/WEB-INF/src/com/learndiary/website/action/mydiaries/MyDiaryAction.java)中處理;

      (3)、在頁面上顯示上一條、下一條導(dǎo)航的URL字符串;
      在需要上一條、下一條導(dǎo)航的頁面上,把從request中獲得的屬性“preNextNavigation”顯示在頁面的右上部和右下部就行了。
  上一條、下一條導(dǎo)航完整的設(shè)計(jì)分析過程見我上面提到的第二篇日記:“分析學(xué)習(xí)日記橫向?qū)Ш郊伴_幾個(gè)窗口的思路”(http://www.learndiary.com/disDiaryContentAction.do?searchDiaryID=&goalID=1167&naviStr=a10a2506ah1128 )。

  3、父帖與子帖列表的雙向?qū)Ш降膶?shí)現(xiàn)過程:

    1)列出導(dǎo)航需求列表:
      (1)“目標(biāo)<──>目標(biāo)下的所有日記列表”的雙向?qū)Ш剑?br />      (2)“目標(biāo)<──>目標(biāo)下我的日記列表”的雙向?qū)Ш剑?br />
    2)分析實(shí)現(xiàn)雙向?qū)Ш剿璧膮?shù):
      只需要目標(biāo)的ID或日記列表的目標(biāo)ID和導(dǎo)航封裝字符串;

    3)確定實(shí)現(xiàn)方法:
      直接在Action中得到當(dāng)前目標(biāo)的ID或日記列表的目標(biāo)ID和導(dǎo)航封裝字符串,附在“***Action.do?”的后面就行了。

    4)進(jìn)行雙向?qū)Ш降脑O(shè)計(jì):
      (1)、確定在哪幾個(gè)Struts的Action中需要處理雙向?qū)Ш剑?br />        1>、在“目標(biāo)──>目標(biāo)下的所有日記列表”和“目標(biāo)──>目標(biāo)下我的日記列表”的導(dǎo)航,需要放在DisGoalContentAction.java(/WEB-INF/src/com/learndiary/website/action/disgoal/DisGoalContentAction.java)中處理;
        2>、在“目標(biāo)下的所有日記列表──>目標(biāo)”的導(dǎo)航,需要放在DiaryAction.java(/WEB-INF/src/com/learndiary/website/action/disdiary/DiaryAction.java)中處理;
        3>、在“目標(biāo)下的我的日記列表──>目標(biāo)”的導(dǎo)航,需要放在在MyDiaryAction.java(/WEB-INF/src/com/learndiary/website/action/mydiaries/MyDiaryAction.java)中處理;
         
      (2)、在頁面上顯示雙向?qū)Ш降腢RL字符串:
      在需要“目標(biāo)──>目標(biāo)下的所有日記列表”和“目標(biāo)──>目標(biāo)下我的日記列表”的導(dǎo)航的頁面上,把從request中獲得的屬性“jumpToViewDiaries”顯示在頁面的右上部和右下部;在“目標(biāo)下的所有日記列表──>目標(biāo)”和“目標(biāo)下的我的日記列表──>目標(biāo)”的導(dǎo)航中,把從request中獲得的屬性“jumpToViewGoal”顯示在頁面的右上部和右下部就行了。

  四、總結(jié):
    1、心得:
      1)、編碼前的分析設(shè)計(jì)是非常重要的,這一步工作做好了,編碼就很輕易了(但我還做得不夠,如下面的第3)條心得。可是,也許是我的水平有限,有些應(yīng)該放在設(shè)計(jì)時(shí)的工作不到編碼的時(shí)候就是想不到,還望大家給予指點(diǎn));
      2)、Struts框架把程序的邏輯實(shí)現(xiàn)代碼和頁面顯示部分能比較好的分離,有利于功能模塊的新增和程序的后期維護(hù);
      3)、在進(jìn)行類和類的方法的設(shè)計(jì)時(shí)(如前面提到的Pager類和PageDB類),沒有先進(jìn)行完整的高層設(shè)計(jì),是采用邊編碼邊設(shè)計(jì)的方式,致使類的設(shè)計(jì)不夠面向?qū)ο螅o后期的理解和維護(hù)會(huì)造成困難;
      4)、假如這種導(dǎo)航設(shè)計(jì)思路真的有用,有必要把它進(jìn)行精心的設(shè)計(jì),做成插件的形式,這樣可以把它方便的應(yīng)用于需要這種動(dòng)態(tài)導(dǎo)航的各種java的web程序中;

    2、這種動(dòng)態(tài)導(dǎo)航的優(yōu)點(diǎn):
      1)、能夠極大的提高用戶的瀏覽體驗(yàn),使網(wǎng)站的導(dǎo)航更符合邏輯和人們的思維習(xí)慣;
      2)、能夠無限的進(jìn)行需要導(dǎo)航的頁面的增加和減少,后期的維護(hù)代碼少量增加就行了;

    3、這種動(dòng)態(tài)導(dǎo)航的缺點(diǎn):
      1)、實(shí)現(xiàn)過程較為復(fù)雜,牽涉的頁面和邏輯代碼較多,權(quán)衡實(shí)現(xiàn)的代價(jià)和收到的效果,真的值得嗎?;
      2)、動(dòng)態(tài)導(dǎo)航能被用戶的使用習(xí)慣接受嗎?這是一個(gè)未知數(shù);
      3)、還有什么缺點(diǎn)呢?暫時(shí)還沒有想出來,大家?guī)臀覀兿胍幌氚伞?br />
    4、愿望:
      1)、希望朋友們能夠?qū)W(xué)習(xí)日記開發(fā)小組提出的這種動(dòng)態(tài)導(dǎo)航技術(shù)展開充分的討論,論證這種導(dǎo)航方式的可行性; 
      2)、希望與軟件相關(guān)(尤其是java )、學(xué)習(xí)相關(guān)(尤其是計(jì)算機(jī)軟件自學(xué) )、開源相關(guān)(尤其是java開源 )的網(wǎng)站結(jié)為友站關(guān)系并交換網(wǎng)站鏈接,共謀發(fā)展。我們的鏈接代碼(請直接復(fù)制代碼,我們的新logo正在醞釀中 ):圖片鏈接:“<a target=_blank><img border=0 src="http://www.learndiary.com/pictures/learndiarylink.gif" alt="我們致力于以JAVA技術(shù)構(gòu)建一個(gè)普遍適用的開源網(wǎng)絡(luò)學(xué)習(xí)交流平臺。"></a>”,文字鏈接:“<a target=_blank>學(xué)習(xí)日記</a>”。假如,你愿意與我們交換鏈接,請把你的鏈接代碼發(fā)至:“mdx-xx@tom.com”。

  五、聯(lián)系方式:
    1、在學(xué)習(xí)日記網(wǎng)站對這篇文章進(jìn)行評論(需要注冊并登錄):http://www.learndiary.com/disDiaryContentAction.do?searchDiaryID=&goalID=1255&naviStr=a10a2167
    2、在學(xué)習(xí)日記網(wǎng)站留言(不需登錄,但留言內(nèi)容只有本站治理員才能查看與回復(fù)):http://www.learndiary.com/toWriteMessageAction.do?typeID=4&goalID=0&naviStr=a10af0
    3、電子郵件:mdx-xx@tom.com
    4、QQ:81251712

  六、附件
  1、學(xué)習(xí)日記V0.9.0.4,簡介:http://www.learndiary.com/disDiaryContentAction.do?goalID=1245&naviStr=a10a21 ;
  下載地址:http://www.learndiary.com/download/learndiaryV0.9.0.4.war ;
  2、學(xué)習(xí)日記系統(tǒng)ArgoUML建模(學(xué)習(xí)日記V0.9.0.4反向工程類圖),下載地址:http://www.learndiary.com/download/learndiaryV0.9.0.4.zargo ;
用ArgoUML V0.20.alpha2打開,ArgoUML下載地址:http://argouml-downloads.tigris.org/nonav/argouml-0.20.ALPHA_2/ArgoUML-0.20.ALPHA_2.zip )。

-全文完
                                             作者:學(xué)習(xí)日記開發(fā)小組(http://www.learndiary.com ,http://develop.learndiary.com )
                                2005年11月26日下午

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 丰镇市| 剑川县| 西宁市| 东台市| 阿巴嘎旗| 鄂托克前旗| 额尔古纳市| 河池市| 武宣县| 三门县| 濉溪县| 内乡县| 馆陶县| 乳源| 竹溪县| 临城县| 湟源县| 彩票| 乃东县| 霍林郭勒市| 长宁县| 星座| 白河县| 墨脱县| 金阳县| 新和县| 格尔木市| 隆回县| 惠东县| 宜丰县| 任丘市| 鹤庆县| 黑河市| 财经| 长岭县| 驻马店市| 富宁县| 盐山县| 庄浪县| 弥渡县| 桂阳县|