详细分析设计过程
我上面提到的第一篇日记中的“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://
java.chinaitlab.com/UploadFiles_8734/200511/20051128145655638.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://
java.chinaitlab.com/UploadFiles_8734/200511/20051128145637393.gif )(路径1)
在检索模块中,导航条为:所有目标>>检索>>检索日记列表>>日记内容;(图例:http://
java.chinaitlab.com/UploadFiles_8734/200511/20051128145638825.gif ) (路径2)
在您的目标中,导航条为:所有目标>>
我进行中的目标>>本目标
我的日记列表>>日记内容;(图例:http://
java.chinaitlab.com/UploadFiles_8734/200511/20051128145639738.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的数组;