麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

Struts網站導航系統設計新思路探討

2019-11-18 12:55:08
字體:
來源:轉載
供稿:網友

  提綱:
  
  一、背境;
  
  二、需求分析:
  1、學習日記網站的主要功能頁面結構;
  2、需要進行動態導航的主要模塊;
  3、需求的提出:
  1)、層次導航的需求;
  2)、同一列表中帖子間的導航(即上一條,下一條類似的導航);
  3)、父帖與子帖列表的雙向導航;
  
  三、具體實現過程:
  1、層次導航的實現過程:
  1)列出導航功能需求列表,看都有哪些導航路徑;
  2)分析定位特定類型的頁面所需的參數;
  3)確定層次導航的實現方法;
  4)進行層次導航系統的設計:
  (1)、進行頁面節點導航封裝字符串格式的設計;
  (2)、頁面完整導航字符串的設計;
  (3)、將封裝的導航字符串還原為顯示在頁面上的URL地址導航條;
  (4)、在頁面上顯示層次導航的URL字符串;
  2、同一列表中帖子間的導航(即上一條,下一條類似的導航)的實現過程:
  1)列出導航需求列表;
  2)分析實現上一條、下一條導航所需的參數;
  3)確定實現上一條、下一條導航的實現方法;
  4)進行上一條、下一條導航的設計:
  (1)、根據層次導航的導航字符串確定上一條、下一條導航所在的層次導航位置;
  (2)、確定在哪幾個Struts的Action中需要處理上一條、下一條導航;
  (3)、在頁面上顯示上一條、下一條導航的URL字符串;
  3、父帖與子帖列表的雙向導航的實現過程:
  1)列出導航需求列表;
  2)分析實現雙向導航所需的參數;
  3)確定實現方法;
  4)進行雙向導航的設計:
  (1)、確定在哪幾個Struts的Action中需要處理雙向導航;
  (2)、在頁面上顯示雙向導航的URL字符串;
  
  四、總結:
  1、心得;
  2、優點;
  3、缺點;
  
  要害詞:學習日記 Struts 動態導航 學習日記動態導航技術(簡稱:LDDN技術 ) 學習日記開發小組(簡稱:LDDG )
  
  ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
  
  正文
  
  一、背境:

  
  學習日記(http://www.learndiary.com )網站是采用Struts框架的開源項目learndiary(http://develop.learndiary.com )的實際運行示范站點。目前由學習日記開發小組進行開發,致力于以java技術構建一個普遍適用的開源網絡學習交流平臺。為了改善用戶的瀏覽體驗,故提出導航系統的改善計劃。已經包含了這個導航系統的的最新版本為learndiaryV0.9.0.4。本文所提到的程序均可以在本站的下載菜單中獲取:http://www.learndiary.com/download/download.Html 。本文希望起到一個拋磚引玉的作用,引發一場關于java技術構建的web系統的導航系統設計的討論。
  
  二、基本思路:
  
  1、學習日記網站的主要功能頁面結構:
  
  核心為:目標列表-》目標內容及評論-》目標下的日記列表-》日記內容及評論
  
  (示意圖:http://www.learndiary.com/pictures/navigationdesign/pagesStrUCture.gif )
  
  2、需要進行動態導航的主要模塊:
  
  需要進行動態導航的主要模塊有3個,見學習日記網站的菜單欄:
  
  1)、所有目標:http://www.learndiary.com/indexAction.do?pageNum=1&naviStr=a10 (顯示學友提出的所有學習目標列表 )
  
  2)、檢索:http://www.learndiary.com/toSearchAction.do?naviStr=a10ac0 (檢索本站的所有學習目標和學習日記 )
  
  3)、您的目標:http://www.learndiary.com/PRocessGoalAction.do?currentGoalState=1&pageNum=1&naviStr=a10a60 (學友自己的學習目標歸類:包括:進行中的目標、退出的目標、已完成的目標 )
  
  3、需求的提出:
  
  1)、層次導航的需求:
  
  我們想建成一個導航系統,它可以跟蹤用戶在系統中瀏覽頁面的過程,每瀏覽到一個新的頁面,就在導航條中加入這個頁面的URL,于是,當用戶瀏覽到別的頁面,可以點擊返回系統導航條中的前面瀏覽過的頁面;當瀏覽一個頁面是與導航條中已經存在的頁面類型一致時,就截去導航條中此類型頁面后面的導航URL。
  
  征對這個需求,我大概看了一下動網的實現方式和phpWind論壇的實現方式,他們用的導航基本上是靜態的,也就是說,一種頁面上的導航條是固定的,例如:顯示一條帖子的內容,他們的方式是:論壇首頁-》論壇版塊-》主題內容。
  
  而我們的需求是,例如:顯示一篇日記的內容:
  
  在所有目標模塊中,導航條為:所有目標>>日記列表>>日記內容;(圖例:http://www.learndiary.com/pictures/navigationdesign/disDiaryInAllGoal.gif )
  
  在檢索模塊中,導航條為:所有目標>>檢索>>檢索日記列表>>日記內容;(圖例:http://www.learndiary.com/pictures/navigationdesign/disDiaryInSearch.gif )
  
  在您的目標中,導航條為:所有目標>>我進行中的目標>>本目標我的日記列表>>日記內容;(圖例:http://www.learndiary.com/pictures/navigationdesign/disDiaryInMine.gif )
  
  2)、同一列表中帖子間的導航(即上一條,下一條類似的導航 ):
  
  另外,除了上面層次導航的需求,同一列表中帖子間的導航(即上一條,下一條類似的導航 ),我們也想在網上一般的導航系統的基礎有所改良。例如:在一般的導航系統中,假如你在檢索結果的列表中點擊查看一篇帖子,然后,你再點擊這篇帖子的上一條和下一條鏈接,新點開的頁面不是檢索結果列表中的上一篇或下一篇帖子,而是這條帖子所有的版塊的上一條和下一條帖子。
  
  我們需要在檢索結果列表中,點擊檢索到的一篇日記中的“上一條”和“下一條”鏈接時,顯示的是檢索結果列表中本日記的上一條和下一條日記。
  
  例如,我們以“中文顯示”為要害字檢索日記得到一個檢索結果列表:(圖例:http://www.learndiary.com/pictures/navigationdesign/diarySearchList.gif )
  
  當我點擊查看“解決:jsp頁面中文顯示問題”這篇日記中的下一條鏈接時,我們需要打開檢索結果列表的下一篇日記:“問題:jsp中文顯示,<c:set>的值可否是對象?me ”:(圖例:http://www.learndiary.com/pictures/navigationdesign/nextDiaryInSearch.gif ),而不是“解決:jsp頁面中文顯示問題”這篇日記所在的目標中的下一篇日記。
  
  在“您的目標”這個模塊中的“上一條”和“下一條”的導航同樣存在在檢索頁面中點擊“上一條”和“下一條”鏈接的問題。
  
  3)、父帖與子帖列表的雙向導航:
  
  學習日記征對自身的功能結構特點,還需要實現:“目標<──>目標下的所有日記列表”的雙向導航和“目標<──>目標下我的日記列表”的雙向導航:顯示目標內容(圖例:http://www.learndiary.com/pictures/navigationdesign/aGoalContent.gif ),您可以看到頁面右邊中上有兩個鏈接分別是:“查看所有日記”和“查看我的日記”,點擊“查看所有日記”鏈接出現的是頁面(圖例:http://www.learndiary.com/pictures/navigationdesign/allDiariesListOfGoal.gif ),點擊“查看我的日記”鏈接出現的是頁面(圖例:http://www.learndiary.com/pictures/navigationdesign/myDiariesListOfGoal.gif );后面這兩個頁面的右中上部又都有到日記所在的目標中的鏈接:“查看目標內容”。
  
  以上總結了學習日記需要實現的導航系統的三個方面的需求,征對這個需求,我看了一些論壇,均沒有現存的東西可以參考,于是,我們決定探索一種能夠實現上面動態導航需求的方法。因為我們實現的導航系統是動態變化的,故把這種實現的方法稱之為“學習日記動態導航技術”(簡稱:LDDN技術 )。下面把我們的具體設計過程總結一下。
  
  三、具體實現過程:
  
  具體的設計分析過程我已經在進行的過程中記錄在日記中了,所以,假如你要具體的了解我的分析設計過程的話,可以去看這兩篇日記:
  
  第一篇日記:“提高學習日記導航能力的思路”(http://www.learndiary.com/disDiaryContentAction.do?searchDiaryID=&goalID=1128&naviStr=a10a2506ah1167 ),主要記錄的是我在對層次導航部分的分析設計過程;
  
  第二篇日記:“分析學習日記橫向導航及開幾個窗口的思路”(http://www.learndiary.com/disDiaryContentAction.do?searchDiaryID=&goalID=1167&naviStr=a10a2506ah1128 ),主要記錄的是我在對“上一條”和“下一條”導航部分的分析與設計過程。
  
  當然,細節總是太煩瑣和令人不愉快的,我把大概的設計過程總結如下:
  
  1、層次導航的實現過程:
  
  1)列出導航功能需求列表,看都有哪些導航路徑,例如:
  
  (5)所有目標列表->相關日記列表->顯示日記內容->編輯評論;
  
  (14)所有目標列表->進行中的目標列表->您的日記列表->顯示日記內容->編輯評論;
  
  (21)所有目標列表->檢索頁面->搜索結果日記列表->相關日記列表->顯示日記內容->撰寫評論;
  
  全部列表請見我上面提到的第一篇日記中的“一、學習日記導航路徑列舉:”(您可以在頁面中搜索位置,前后的雙引號除外,下同 )。
  
  2)分析定位特定類型的頁面所需的參數(這樣,就可以根據頁面類型和參數唯一的確定一個頁面了 ):
  
  經過分析,唯一定位一個頁面所需要的參數變為:
  
  1》頁面類型;
  
  2》參數ID;
  
  其中參數ID分為下面幾種情況:
  
  1》列表:需要列表的parentID;
  
  2》單個條目:需要它的ID;
  
  3》用戶的進行、完成等目標列表:什么都不需要,用戶ID在session中;
  
  4》用戶的進行、完成等目標的用戶日記列表;目標ID,所需的用戶ID在Session中;
  
  5》搜索列表:什么都不需要,因為搜索條件字符串已保留在全局Session中了;
  
  具體的分析過程請見我上面提到的第一篇日記中的“(2 )、如何唯一的定位一個特定的頁面呢? ”
  
  3)確定層次導航的實現方法:
  
  當點擊一個新的頁面時,就把定位這個頁面所需的參數加入到層次導航的參數鏈表中(鏈表的一個節點儲存的是一個新的頁面的定位參數 ),這時鏈表變長;當點擊一個在鏈表中已經存在這種類型的頁面(例如:顯示一篇日記的內容的頁面 )時,就把在導航鏈表中這個節點及后面的節點刪除,再加上這個點擊的頁面的定位參數。
  
  實現這種層次導航的需求有兩種方法:
  
  (1)、為每條導航路徑在session中設置一個層次導航所需的屬性,在這條路徑上導航鏈表的增長和縮短信息就由這個屬性來維持;
  
  (2)、把這個鏈表封裝成字符串,這個字符串在訪問不同的頁面時,會根據上面的思路不斷增長和縮短。把這個封裝的字符串連同用戶新請求的頁面的定位參數節點字符串一起傳給請求這個頁面前的Struts的action,形成新的頁面上導航條所需的編碼字符串,然后把這個編碼字符串保存在request中,供請求的頁面中的下一個鏈接使用;并同時由action把這個形成的編碼導航字符串解碼處理成用戶請求的頁面上需要的導航字符串。
  
  經過分析,我決定采用第(2 )種方法來實現層次導航。
  
  具體的分析過程請見我上面提到的第一篇日記中的“我知道有2種方法可以解決這個問題 ”。
  
  4)進行層次導航系統的設計:
  
  (1)、進行頁面節點導航封裝字符串格式的設計:
  
  分隔符(用'a'作分隔符 )+頁面節點類型(用一位字符代表,封裝成一個頁面類型常量類,用字符1-9,英文字符b-z和A-Z表示 )+頁面參數ID(如顯示目標的日記列表所需的目標ID,顯示日記內容所需的日記ID )。如顯示一篇日記的頁面類型常量為字符:‘h’,那么,顯示“解決:jsp頁面中文顯示問題”這篇日記內容(ID為292 )這一頁面的封裝字符串為:ah292;
  
  (2)、頁面完整導航字符串的設計:
  
  在下面的討論中會用到的相關源文件:
  
  負責封裝學習日記所需導航的頁面的類型常量(/WEB-INF/src/com/learndiary/website/PageTypeConsts.java );
  
  負責導航字符串封裝的方法(/WEB-INF/src/com/learndiary/website/util/Pager.java中的public static String encodeNaviStr(String naviStr, char toPageType, String parameter) );
  
  當用戶提出一個新的頁面請求,把當前頁面中的完整的導航封裝字符串和新的頁面的類型和新請求頁面的參數ID傳給處理新頁面顯示前的Struts中的Action中,由Action調用一個方法,負責把這些參數組裝成下一新頁面所需的導航字符串。如:當前正顯示的頁面是“系統導航:所有目標>>我進行中的目標>>目標:一起學習Struts(MVC)我的日記列表”中的“目標:一起學習Struts(MVC)我的日記列表”(圖例:http://www.learndiary.com/pictures/navigationdesign/myDiariesList.gif ),你可以看到當點擊顯示日記“解決:jsp頁面中文顯示問題 (0篇) ”的URL中的導航字符串為:“naviStr=a10a60a0167”(圖例中左下方紅圈中 ),把這個字符串和請求的顯示日記的頁面類型(日記為:‘h’ )和顯示這篇日記所需的ID(292 )傳給顯示日記內容前的Action中(disDiaryContentAction.do,源文件為:/WEB-INF/src/com/learndiary/website/action/disgoal/DisGoalContentAction.java ),由負責導航字符串封裝的方法(源文件為:/WEB-INF/src/com/learndiary/website/util/Pager.java中的public static String encodeNaviStr(String naviStr, char toPageType, String parameter) )進行處理,處理流程為:以顯示日記這個頁面的類型ID為‘h’搜索已有導航字符串,沒有相同的頁面,于是就把這個頁面導航字符串節點(ah292 )加到完整的導航字符串(a10a60a0167)后面得到新的導航字符串(a10a60a0167ah292 ),見例圖:(http://www.learndiary.com/pictures/navigationdesign/disDiaryInMine2.gif ),你可以看到當點擊“日記:解決:jsp頁面中文顯示問題”這篇日記中的“我要評論”的URL中的導航字符串為:“naviStr=a10a60a0167ah292”(圖例中左下方紅圈中 );
  
  當點擊當前頁面中的回到上級導航節點的鏈接時,如:“系統導航:所有目標>>我進行中的目標>>目標:一起學習Struts(MVC)我的日記列表”中的“我進行中的目標”,這時顯示“我進行中的目標”頁面的類型代碼是‘6’,參數ID是“0”,那么以新頁面的節點字符串(a60 )的類型代碼‘6’搜索已有導航字符串,已經存在相同的類型代碼,于是,就把導航字符串中這個節點和后面的所有節點刪除得到字符串“a10”,再加上新頁面的節點字符串為“a60”,得到顯示“我進行中的目標”頁面的導航字符串為“a10a60”,見例圖:(http://www.learndiary.com/pictures/navigationdesign/myProcessGoals.gif ),你可以看到當點擊“一起學習Struts(MVC) (19篇)”這篇目標的URL中的導航字符串為:“naviStr=a10a60”(圖例中左下方紅圈中 );
  
  具體分析設計過程我上面提到的第一篇日記中的“2、設計中用到的方法: ”;
  
  (3)、將封裝的導航字符串還原為顯示在頁面上的URL地址導航條:
  
  同樣用上面的顯示在“我進行中的目標”中目標“一起學習Struts(MVC)我的日記列表”中的日記“解決:jsp頁面中文顯示問題”來進行說明,也就是說:如何把導航封裝字符串“a10a60a0167ah292”轉換成字符串“系統導航:<a href="/learndiary/indexAction.do?searchDiaryID=&pageNum=1&naviStr=a10a60a0167ah292">所有目標</a>>><a href="/learndiary/processGoalAction.do?searchDiaryID=¤tGoalState=1&pageNum=1&naviStr=a10a60">我進行中的目標</a>>><a href="/learndiary/myDiaryAction.do?searchDiaryID=&pageNum=1&goalID=167&naviStr=a10a60a0167ah292">目標:一起學習Struts(MVC)我的日記列表</a>>>日記:解決:jsp頁面中文顯示問題<p>”,
  
  使它在頁面上顯示導航條為“系統導航:所有目標>>我進行中的目標>>目標:一起學習Struts(MVC)我的日記列表>>日記:解決:jsp頁面中文顯示問題”(見圖例:http://www.learndiary.com/pictures/navigationdesign/disDiaryInMine2.gif )?
  
  解決這個問題我用兩步走的方法:
  
  <1>、用一個方法可以把每一個導航節點的封裝字符串轉換為導航URL字符串。主要是根據需要顯示的頁面類型和參數ID來進行轉換,實現過程比較簡單,請查看源文件中負責解封導航節點封裝字符串的方法(/WEB-INF/src/com/learndiary/website/util/Pager.java中的public static String decodeNodeStr(String naviStr, String nodeNaviStr, HttpServletRequest request, boolean ifLast) throws Exception );
  
  <2>、把每個節點封裝的字符串聯接在一起,形成完成的頁面層次導航所需的URL字符串。根據慣例,當前(也就是最后一個節點的導航URL灰化,無鏈接 )。具體實現請查看源文件中負責解封整個導航封裝字符串的方法(/WEB-INF/src/com/learndiary/website/util/Pager.java中的public static String decodeNaviStr(String naviStr, HttpServletRequest request) throws Exception );
  
  具體的分析設計過程請見我上面提到的第一篇日記中的“把封裝的字符串轉化為下一個頁面顯示導航條所需要的字符串”。
  
  (4)、在頁面上顯示層次導航的URL字符串
  
  在需要層次導航的頁面上,把從request中獲得的屬性“navigation”顯示在頁面的左上部,并把從request中獲得的相應的封裝導航字符串naviStr作為參數附在每一個URL的后面就行了。
  
  至此,學習動態導航系統中的層次導航部分已經設計完成,下面繼續進行顯示“上一條”和“下一條”的水平導航部分的探索。
  
  2、同一列表中帖子間的導航(即上一條,下一條類似的導航 )的實現過程:
  
  1)列出導航需求列表:
  
  (1)、在所有目標列表中:
  
  1>目標內容;
  
  2>目標的日記列表(上一條:在這里即上一目標的日記列表);
  
  3>日記列表中的日記內容;
  
  (2)、在檢索結果頁面中:
  
  1>檢索目標列表:
  
  <1>目標內容;
  
  <2>目標的日記列表;
  
  <3>日記列表中的日記內容;
  
  2>檢索日記列表:
  
  <1>日記內容;
  
  <2>所在目標的日記列表中的日記內容;
  
  (3)、您的進行中的目標列表:
  
  1>目標內容;
  
  2>目標的全部日記列表;
  
  3>目標的我的日記列表;
  
  4>目標的全部日記列表中的日記;
  
  5>目標的我的日記列表中的日記;
  
  2)分析實現上一條、下一條導航所需的參數:
  
  因為是實現同一列表中的同一級別的帖子之間的導航,所以只需要得到需要導航的條目的ID就行了,其它所有參數都不必改變。
  
  3)確定實現上一條、下一條導航的實現方法:
  
  現在的問題是:如何根據當前條目的ID,得到上一條目和下一條目的ID呢?
  
  答案是:條目的列表,條目在列表中的排序方式,當前條目的ID。為了在查詢結果集中得到當前條目的前后條目的ID,可以有下面的方法:
  
  (1)在一個直接操縱數據庫的方法中從查詢結果集中取出每個ID(整型)后,保存在數組中,馬上關閉數據庫連接,減少數據庫連接開銷。然后在同個方法中取得前面、當前、后面記錄的ID,只返回這3個元素的數組給Pager類(負責產生頁面導航所需要的URL字符串的工具類)處理,這樣,可以保證每條數據都是最新的,但是要不停的開啟和關閉數據庫連接;
  
  (2)把查詢結果產生的數組全部存在session中,Pager在session中取數據。這樣,可以減少數據庫的查詢,但是存在兩個問題,那個比較長的數組在session中始終占用內存,還有,取出的數據的排序關系可能是過期的(這時,有人往數據庫中增加或修改了數據)。
  
  我覺得第一種方法可以減輕對網站虛擬主機資源的壓力,決定采用第一種方法。
  
  另外,在直接操縱數據庫產生的結果集中查詢鄰近的ID會出現幾種結果呢?
  
  這里用“-1”表示沒有相應的帖子。
  
  1>在用戶查看帖子期間,這篇帖子被刪除了,結果返回:{-1,-1,-1};
  
  2>只有一篇符合要求的帖子,結果返回:{-1,當前帖子ID,-1};
  
  3>當前帖子是第一篇帖子,結果返回:{-1,當前帖子ID,下一條帖子ID};
  
  4>當前帖子是最后一篇帖子,結果返回:{上一篇帖子ID,當前帖子ID,-1};
  
  5>當前帖子前后都有帖子,結果返回:{上一篇帖子ID,當前帖子ID,上一篇帖子ID};
  
  現在,就可以把這個含有前一條、當前、后一條帖子ID的整型數組傳給Pager類中的產生上一條、下一條導航URL字符串的相應方法進行處理了。
  
  下面是上一條、下一條導航的具體設計。
  
  4)進行上一條、下一條導航的設計:
  
  (1)、根據層次導航的導航字符串確定上一條、下一條導航所在的層次導航位置:
  
  進行上一條、下一條的導航需要知道被導航的帖子所在的層次導航的位置。例如:顯示一篇日記的內容:
  
  在所有目標模塊中,導航條為:所有目標-》日記列表-》日記內容;(圖例:http://www.learndiary.com/pictures/navigationdesign/disDiaryInAllGoal.gif )(路徑1)
  
  在檢索模塊中,導航條為:所有目標>>檢索>>檢索日記列表>>日記內容;(圖例:http://www.learndiary.com/pictures/navigationdesign/disDiaryInSearch.gif ) (路徑2)
  
  在您的目標中,導航條為:所有目標>>我進行中的目標>>本目標我的日記列表>>日記內容;(圖例:http://www.learndiary.com/pictures/navigationdesign/disDiaryInMine.gif ) (路徑3)
  
  在上一條、下一條的導航中,層次導航條除了上一條目和下一條目內容的改變,其余是不會變的;而且,要得到當前條目的前后條目的ID,在不同的層次導航中是不同的。例如:在上面的路徑1中,得到日記列表的查詢條件是本目標下的所有日記;在路徑2中,得到日記列表的查詢條件是檢索頁面的條件組合;在路徑3中,得到日記列表的查詢條件是本目標下的用戶的所有日記。而且,在學習日記的設計中,這三種情況的排序方式是分開的,可以由用戶在瀏覽時自選的。
  
  為了得到不同層次導航下的上一條、下一條URL導航字符串,我在頁面導航URL字符串產生工具類Pager((/WEB-INF/src/com/learndiary/website/util/Pager.java)中用了3個重載的、用于產生上一條、下一條導航URL字符串的方法來征對不同的三種情況(與前面說的3種路徑不是一一對應的),分別是:
  
  1>、(包括對這一路徑下的目標列表中目標的瀏覽和目標的日記列表的瀏覽,和檢索目標列表中目標的瀏覽,和檢索日記列表中日記的瀏覽):public static String getPreNextNaviStr( char toPageType, String url, HttpServletRequest request, String naviStr, int currentID, String condition,int orderType, int direction) throws Exception。輸入參數是:toPageType-請求的頁面類型,url-請求的頁面的“/***Action.do”路徑,request-請求對象,naviStr-當前頁面的導航封裝字符串,currentID-當前條目的ID,condition-查詢的where子句,orderType-排序類型,direction-排序方向。為了分離數據庫訪問的代碼,在這個方法中調用了一個直接訪問數據庫的類(/WEB-INF/src/com/learndiary/website/db/PageDB.java)中的方法(public int[] getAdjacentIDs(String tableName, int currentID, String condition, int orderType, int direction) throws Exception )來得到含有前一條、當前、后一條帖子ID的數組;
  
  2>、(包括對檢索日記列表的日記所在目標、日記所在目標下的日記列表的瀏覽):public static String getPreNextNaviStr(String url, HttpServletRequest request, String naviStr, int searchDiaryID, String condition,int orderType, int direction) throws Exception。輸入參數是:url-請求的頁面的“/***Action.do”路徑,request-請求對象,naviStr-當前頁面的導航封裝字符串,searchDiaryID-搜索日記列表中當前日記的ID,condition-查詢的where子句,orderType-排序類型,direction-排序方向。為了分離數據庫訪問的代碼,在這個方法中調用了一個直接訪問數據庫的類(/WEB-INF/src/com/learndiary/website/db/PageDB.java)中的方法(public int[] getAdjacentIDs(String tableName, int currentID, String condition, int orderType, int direction) throws Exception )來得到含有前一條、當前、后一條帖子ID的數組;
  
  3>、(包括對進行中的目標、退出的目標、完成的目標列表中目標的瀏覽):public static String getPreNextNaviStr(String url, HttpServletRequest request, String naviStr, int userID, int currentID, int myGoalTypeFlag, int orderType, int direction) throws Exception。輸入參數是:url-請求的頁面的“/***Action.do”路徑,request-請求對象,naviStr-當前頁面的導航封裝字符串,userID-當前用戶ID,currentID-當前條目的ID,myGoalTypeFlag-用戶目標的類型(進行、退出、或者完成),orderType-排序類型,direction-排序方向。為了分離數據庫訪問的代碼,在這個方法中調用了一個直接訪問數據庫的類(/WEB-INF/src/com/learndiary/website/db/PageDB.java)中的方法(public int[] getAdjacentIDs(int userID,int currentID, int myGoalTypeFlag, int orderType, int direction) throws Exception)來得到含有前一條、當前、后一條帖子ID的數組;
  
  現在的問題是怎么樣來區別上面1>、2>、3>中列出的各種情況,并調用對應的“getPreNextNaviStr”方法來產生正確的上一條、下一條的URL導航字符串呢?
  
  我的答案是根據當前頁面的封裝導航字符串來確定,我通過分析上面1>、2>、3>中列出的各種情況的導航字符串的特征碼,然后在程序中通過檢索特征碼來確定當前頁面的層次導航位置(對應于上面不同的幾種情況),這是一個煩瑣的過程,這里僅列舉一二:
  
  例如:在檢索目標的列表中的目標頁面中的封裝導航串一定會含有“ae”兩個字符,且帖子類型為“目標”;在檢索日記的列表中的日記頁面中的封裝導航串一定會含有“ad”兩個字符,且帖子類型為“日記”。
  
  (2)、確定在哪幾個Struts的Action中需要處理上一條、下一條導航:
  
  1)、首先,需要導航的地方有三種情況:
  
  1>、目標內容
  
  2>、日記內容
  
  3>、目標的日記列表
  
  2)、
  
  1>、1)的1>和2>需要放在DisGoalContentAction.java(/WEB-INF/src/com/learndiary/website/action/disgoal/DisGoalContentAction.java)中處理;
  
  2>、1)的3>需要分在幾個地方處理,分別是:
  
  1>檢索目標的日記列表,所有目標的日記列表,進行、完成、退出的日記列表:在DiaryAction.java(/WEB-INF/src/com/learndiary/website/action/disdiary/DiaryAction.java)中處理;
  
  2>進行、完成、退出的我的日記列表:在MyDiaryAction.java(/WEB-INF/src/com/learndiary/website/action/mydiaries/MyDiaryAction.java)中處理;
  
  (3)、在頁面上顯示上一條、下一條導航的URL字符串;
  
  在需要上一條、下一條導航的頁面上,把從request中獲得的屬性“preNextNavigation”顯示在頁面的右上部和右下部就行了。
  
  上一條、下一條導航完整的設計分析過程見我上面提到的第二篇日記:“分析學習日記橫向導航及開幾個窗口的思路”(http://www.learndiary.com/disDiaryContentAction.do?searchDiaryID=&goalID=1167&naviStr=a10a2506ah1128 )。
  
  3、父帖與子帖列表的雙向導航的實現過程:
  
  1)列出導航需求列表:
  
  (1)“目標<──>目標下的所有日記列表”的雙向導航;
  
  (2)“目標<──>目標下我的日記列表”的雙向導航;
  
  2)分析實現雙向導航所需的參數:
  
  只需要目標的ID或日記列表的目標ID和導航封裝字符串;
  
  3)確定實現方法:
  
  直接在Action中得到當前目標的ID或日記列表的目標ID和導航封裝字符串,附在“***Action.do?”的后面就行了。
  
  4)進行雙向導航的設計:
  
  (1)、確定在哪幾個Struts的Action中需要處理雙向導航:
  
  1>、在“目標──>目標下的所有日記列表”和“目標──>目標下我的日記列表”的導航,需要放在DisGoalContentAction.java(/WEB-INF/src/com/learndiary/website/action/disgoal/DisGoalContentAction.java)中處理;
  
  2>、在“目標下的所有日記列表──>目標”的導航,需要放在DiaryAction.java(/WEB-INF/src/com/learndiary/website/action/disdiary/DiaryAction.java)中處理;
  
  3>、在“目標下的我的日記列表──>目標”的導航,需要放在在MyDiaryAction.java(/WEB-INF/src/com/learndiary/website/action/mydiaries/MyDiaryAction.java)中處理;
  
  (2)、在頁面上顯示雙向導航的URL字符串:
  
  在需要“目標──>目標下的所有日記列表”和“目標──>目標下我的日記列表”的導航的頁面上,把從request中獲得的屬性“jumpToViewDiaries”顯示在頁面的右上部和右下部;在“目標下的所有日記列表──>目標”和“目標下的我的日記列表──>目標”的導航中,把從request中獲得的屬性“jumpToViewGoal”顯示在頁面的右上部和右下部就行了。
  
  四、總結:
  
  1、心得:
  
  1)、編碼前的分析設計是非常重要的,這一步工作做好了,編碼就很輕易了(但我還做得不夠,如下面的第3)條心得。可是,也許是我的水平有限,有些應該放在設計時的工作不到編碼的時候就是想不到,還望大家給予指點);
  
  2)、Struts框架把程序的邏輯實現代碼和頁面顯示部分能比較好的分離,有利于功能模塊的新增和程序的后期維護;
  
  3)、在進行類和類的方法的設計時(如前面提到的Pager類和PageDB類),沒有先進行完整的高層設計,是采用邊編碼邊設計的方式,致使類的設計不夠面向對象,給后期的理解和維護會造成困難;
  
  4)、假如這種導航設計思路真的有用,有必要把它進行精心的設計,做成插件的形式,這樣可以把它方便的應用于需要這種動態導航的各種java的web程序中;
  
  2、這種動態導航的優點:
  
  1)、能夠極大的提高用戶的瀏覽體驗,使網站的導航更符合邏輯和人們的思維習慣;
  
  2)、能夠無限的進行需要導航的頁面的增加和減少,后期的維護代碼少量增加就行了;
  
  3、這種動態導航的缺點:
  
  1)、實現過程較為復雜,牽涉的頁面和邏輯代碼較多,權衡實現的代價和收到的效果,真的值得嗎?;
  
  2)、動態導航能被用戶的使用習慣接受嗎?這是一個未知數;
  
  3)、還有什么缺點呢?暫時還沒有想出來,大家幫我們想一想吧。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 国产电影精品久久 | 日日天日日夜日日摸 | japanesexxxx24videofree| 精品一区二区免费视频视频 | 国产精品av久久久久久网址 | 亚洲国产精品久久久久久久久 | 国产88久久久国产精品免费二区 | 成人三级电影网 | 国内精品视频饥渴少妇在线播放 | 中国洗澡偷拍在线播放 | 久久久久久久免费精品 | 成人精品一区二区三区中文字幕 | 欧美成人免费在线视频 | 精品国产91久久久久久久 | av免费av | 欧美性a视频| 成人18免费观看 | 欧洲精品久久久 | 99精品视频在线观看免费播放 | 青青草成人免费视频在线 | 久久久久99999| 精品在线观看一区二区三区 | 黄色av一区二区三区 | 视频一区二区三区在线播放 | 中文字幕精品一二三四五六七八 | 色婷婷久久久 | 国产艳妇av视国产精选av一区 | 国产一级免费视频 | 欧美视频在线一区二区三区 | 娇妻被各种姿势c到高潮小说 | 日本成人在线免费 | 免费中文视频 | 日韩黄色一级视频 | 国产精品久久久久久久久久久久午夜 | 黄色片在线播放 | 美女91视频 | 天天看成人免费毛片视频 | 黄色片免费看网站 | 免费观看一级黄色片 | 日本欧美中文字幕 | 一区国产在线 |