静态页面嵌入jsp动态页面的一些总结和疑问

在一个实现将JSP动态页面转为静态的方案(转帖)中后面的那种方法基本上完成了本站的动态页面静态化工作,下面是一些总结和疑问。希望能给碰到类似情况的朋友一点启发。也希望有朋友能够启发一下我在文中提到的疑问。谢谢。

1、页面菜单上部的用户信息是用iframe嵌入的,像下面:


   <!-- show user state with iframe framework -->

   <iframe frameborder="0" name="user_state" width="771" height="30" scrolling="no" src="/common/userState.jsp"></iframe>

/common/userState.jsp是从当前session中取出用户的相关信息显示出来。

不过,我发现: 在firefox中位置不动的信息条在IE中却可以用鼠标上下移动,而且,始终位置在底部,还把字脚给挡住了,搞不懂怎么做了?(注:这个问题已经解决,见:怎样控制iframe内嵌网页的位置

,2006年12月29日10:30分, littlebat)

2、显示日记或目标的帖子下面的游客回复框也是用iframe嵌入的,像下面:


   <iframe frameborder="0" name="guest_reply" width="771" height="456" align="center" scrolling="auto" src="/common/guestReply.jsp?parentID=<c:out value=""/>&defaultTitle=<c:out value=""/> "></iframe>

这个有几点自己的总结:

1)、url中文参数的传递要编码:如:


<%

  //encode default title

  String oriTitle = "re:" + ((ArticleInfo)request.getAttribute("aGoal")).getArticleName();

  String encodedDefaultTitle= URLEncoder.encode(oriTitle, "UTF-8");

  pageContext.setAttribute("encodedDefaultTitle", encodedDefaultTitle);

%>

使用时再解码,如:


        String encodedDefaultTitle = request.getParameter("defaultTitle");

        String defaultTitle = URLDecoder.decode(encodedDefaultTitle, "UTF-8");

        pageContext.setAttribute("defaultTitle", defaultTitle);

2),当前页面处理的信息可以放入pageContext中(如:pageContext.setAttribute("defaultTitle", defaultTitle);),它的作用域应该是当前页面,可以用 <c:out value=""/> 之类的技术取出来,jsp的方法不知道。

3),为了使嵌入的jsp页面中的form提交后能够返回它的被嵌入的_parent页面,可以在form提交时加 target="_parent"解决,如下:


<html-el:form action="postGuestArtAction.do?typeID=3&goalID=" target="_parent" method="POST">

...

</html-el:form>

3、页面计数:

用script做的,如下:


<script language="javascript" src="/count.do?artID=<c:out value=""/>"></script>

疑问:

1)、怎样在script中调用程序,得到当前页面的实时点击数并写入页面的合适位置?上面的功能只能计数,然后统一生成页面更新计数;

2)、本来上面的count.do可以用count.jsp来做的,也许这样还要好点,但是我不知道怎样在jsp中调用struts中的数据源?用jdbc连接常常形成连接数超出空间允许的最大值而不能正确计数;

在struts的action中这样调用数据源:javax.sql.DataSource ds = getDataSource(request, "myDataSourceName");

4)、当用*.jsp后缀名作为静态文件时,提交新日记或目标后,第一次查看会有编译等待jsp的时间,但是写日记和目标毕竟是很少时候,99.99%的时候还是在看的。选用*.jsp是我动过脑子的,最终要是证明错了我也不后悔。因为,我曾经努力过。

4、因为,听说搜索引擎会跟进frame中的框架页面,也不知道会不会跟进iframe的页面,把那两个动态的jsp页面的url写进了robots.txt中禁止搜索引擎抓取这些没有实际意义的东西。像下面:


User-agent: *

Disallow: /common/userState.jsp

Disallow: /common/guestReply.jsp

Disallow: /count.do

本站完整的robots.txt见:http://java.learndiary.com/robots.txt

里面主要禁止搜索引擎访问一些个人才会用的功能,我是第一次写robots.txt,哪位朋友看了发现有问题请一定给我提示一下,谢谢。

页面静态化和网站地图生成,下一步做什么。。。

完成页面静态化和网站地图生成模块的主体部分,思维有点乱,理一下下一步应该做什么。

1、页面静态化:

   1)、把登录信息和游客留言的表单、页面计数各写进一个单独的jsp文件,然后用javascript或jframe调用;

   2)、为了统一,菜单栏的登录用户能够看见的项目使游客也可看见,减少静态化后页面处理的复杂度;

   3)、在目标页面的订阅邮件和退订邮件的提示信息有问题,要修正;

   4)、当更新一篇帖子后(修改或发评论后),当前帖子的原来的上一条和下一条帖子、原来的首条帖子都需要重新生成静态文件,不然这几条帖子的上一条、下一条导航要出现问题;考虑生成的时机;

   5)、上一条、下一条导航是按默认的最近更新排列的,为了与原来的动态选择排列顺序,考虑是否这种上一条、下一条的导航也用一个单独的jsp文件执行,然后用javascript或iframe调用;

   6)、帖子列表是否也静态化,静态化了排序功能就没有了;

   7)、删除一篇帖子的评论后不能在当时按设想更新静态文件,所以采取了重新显示帖子的过程中重新生成静态文件,需要找出原因;

2、网站地图生成:

   1)、继续完成在提交帖子或更新时的网站地图更新,现在是手动全部一次更新; 

3、这两天做静态化都是在网上调试的,还是应该在本地调试好后才传上去为好,免得让来访的朋友看见莫名其妙的东西:)

JAVA学习日记网站地图生成模块方案

JAVA学习日记网站地图生成模块设计

想法太多,想法太成熟,只会使事情停滞不前。不管怎样,先把网站地图生成模块做一个出来再说。

为了使导航更加方便用户和使搜索引擎更好的遍历,设计网站地图模块。

为了灵活性起见,网站地图同样采用前面的静态页面生成方法,生成的静态文件采用jsp文件,再在生成的文件前面加上通过控制语句(比如301转向,使本站的网址统一在域名:http://java.learndiary.com/下)。

一)、需求:

需要生成的网站地图采用树型结构。

一个所有目标地图goals-1.jsp(http://java.learndiary.com/sitemaps/goals-1.jsp),包括全部公共目标的链接(标题含链接)、创建者,创建日期,日记数目,查看次数;或者就是链接:“目标:学习Jsp的所有日记”,这个页面的标题就叫<a href="http://java.learndiary.com/" title="分享目标,分享分享快乐。">JAVA学习日记</a>所有目标列表

这个网页的title就写作:JAVA学习日记所有目标列表(一) - JAVA学习日记网站地图

每100个目标一页,然后第二个一百页就是goals-2.jsp,以此类推。

然后就是各个目标的日记列表地图:如goal1-1.jsp(http://java.learndiary.com/sitemaps/goal1-1.jsp,为goal加上目标的ID加上页码,每100篇日记1页,以此类推)。

每个目标标题的链接到这个目标的所有日记列表。

这个页面的标题就叫:目标:<a href="" title="">学习Jsp</a>的所有日记列表(一)

这个网页的title就写作:目标:学习Jsp的所有日记列表(一) - JAVA学习日记网站地图

二)、实现:

网站地图生成与维护由MapGenerator.java负责。

它的功能有:

public static void doPostArt(ArticleInfo postedArt, TransContext trans)

throws Exception {}

public static void doEditArt(

ArticleInfo oldArt,

ArticleInfo newArt,

TransContext trans,

HttpServletRequest request)

throws Exception {}

public static void doDelArt(

ArticleInfo delArt,

TransContext trans,

HttpServletRequest request)

throws Exception {}

        public static void updateAll(TransContext trans) throws Exception {}

public static boolean isExist(

String fileVirtualName,

HttpServletRequest request) {}

public static void delete(

String fileVirtualName,

HttpServletRequest request) {}

MapGenerator.java将调用一次或多次CallHtml.java中的 public static void callOnePage(String fileName, int artID, int pageNum)方法,来产生相应的一页或多页jsp静态页面(当条目数超过100条时(SITEMAP_ENTRIES_NUM=100))。

而CallHtml.java将调用MapGenerateAction.java来生成相应的动态页面,以此来生成静态的页面。在其中应该注意私有的日记和目标不能生成网站地图。

MapGenerateActon的调用形式可以是: mapGenerateAction.do?artID=1&pageNum=1

整体思路与前两天的JAVA学习日记页面静态化方案类似,生成的时机也类似,不过有不同的地方就是一个目标可能要生成不止一篇列表。

mapGenerateAction需要产生一些数据供实际显示内容的动态jsp文件(这里命名为:siteMap.jsp)

根据前面的需求,产生siteMap.jsp需要的数据包括:

1)、地图的类型:是目标列表还是日记列表,这由artID来定,artID=0表示显示目标列表;artID!=0表示显示所代表的目标的日记列表;

2)、页码:因为一个目标的日记数可能超过100,所以需要根据页码产生当前页。

3)、为了显示页的标题,需要把当前目标传入,类型是ArticleInfo,至于显示所有目标的列表的地图的标题可以造一个ArticleInfo。其中要包括含有的条目数;条目数大于100就要在标题中显示下一页的链接;

4)、目标下面包含的条目信息,是一个以ArticleInfo为子元素的List。

上面1)和2)可以从参数parameter中取得,3)和4)则必须从request.getAttribute()中取得;

CallHtml.java中的 public static void callOnePage(String fileName, int artID, int pageNum){}

fileName可以是siteMap,artID和pageNum的含义同上面的mapGenerateAction.do?artID=1&pageNum=1一样。

而CallHtml的callOnePage方法调用的实际生成jsp静态页面的程序是:

public class ToHtml extends HttpServlet{}

原来的这个类只生成帖子内容的html文件,现在的区别是在生成的静态文件头部额外加上一段jsp公共处理程序,然后把文件扩展名改为:jsp。

在MapGenerator.java中针对每种情况的处理都要考虑有时一个目标的页面生成过程要调用不止一次。这就需要在方法中判断列表的帖子数是否大于SITEMAP_ENTRIES_NUM=100,然后根据列表的帖子数决定调用几次CallHtml中的callOnePage()方法。

下面就开始动手编码吧。

An error happend in setEntries() of RSSGenerator.java


2006-12-11 08:12:11,875 - get feed of latestAdvicesOfGoal:feedType=rss_2.0 entriesNum=10 channelID=2747, channelName is:注册用户公告信息发布区; User: unknown IP: 65.55.212.140 USER-AGENT: msnbot-media/1.0 (+http://search.msn.com/msnbot.htm) REFERER: null

2006-12-11 08:12:12,953 - User: userID:-1,userName:guest; IP: 65.55.212.140 USER-AGENT: msnbot-media/1.0 (+http://search.msn.com/msnbot.htm) REFERER: null

2006-12-11 08:12:15,593 - An error happend in setEntries() of RSSGenerator.javaYou have an error in your SQL syntax.  Check the manual that corresponds to your MySQL server version for the right syntax to use near ') ORDER BY writeDate DESC' at line 1

2006-12-11 08:12:15,609 - get feed of latestAdvicesOfMyDiaries:feedType=rss_2.0 entriesNum=10 userName=guest; User: unknown IP: 65.55.212.140 USER-AGENT: msnbot-media/1.0 (+http://search.msn.com/msnbot.htm) REFERER: null

RSS订阅在thunderbird中有时会出现丢失条目的情况,但是在新浪点点通和其它RSS阅读器中又没有发现问题。

而且,我时不时在网站日志中发现上面的错误信息“An error happend in setEntries() of RSSGenerator.java”。

现在把它记在这里,好好查一查,说不定能找出在thunderbird中RSS订阅有问题的情况。

也许,我中了seo的毒了?

从理论上讲,www.javaeye.com的静态文件列表对搜索引擎来说有内容复制之嫌疑。

如:这篇帖子:confluence不支持群集,是因为hibernate吗?

在静态文件列表中是:http://www.javaeye.com/t/20169.html

而在动态文件列表中是:http://www.javaeye.com/topic/20169

也就是说,相同的内容在他们页面有两个版本,一个动态的,一个静态的。

我不知道这对它们在搜索引擎中的收录有什么影响?

也许,我现在考虑搜索引擎考虑得太多了。

像这两天又想在虚拟主机提供商端实现彻底的301重定向,但是到现在为止也还没有成功。

做网站,或者更坦白的说,学习知识的我不应该在为迁就搜索引擎而折磨自己了。

还有,我发现一个著名的linux个人站linux.vbird.org,他有两个域名:http://linux.vbird.orghttp://www.vbird.org,进入都是同样的返回200 ok状态码;还有他的文章如: DNS 伺服器設定 两个域名都返回的是200码

http://www.vbird.org/linux_server/0350dns.php

http://linux.vbird.org/linux_server/0350dns.php

也就是说,也有内容复制之嫌。

但是以“DNS 伺服器設定”为关键字检索site:linux.vbird.org有结果,而site:www.vbird.org却没有这篇文章的影子,只有这篇文章的老版本:http://www.vbird.org/linux_server/0350dns/0350dns.php存在,而且,这篇老文章被标记成了补充材料。

另外,另一篇文章(Enterprise Linux 实战讲座前言DNS 反解( Reverse Lookup )原理)的pdf文件:

http://linux.vbird.org/somepaper/20050630-dns-1.pdf分在了linux.vbird.org,

而同样文章的第二部分却分在了:www.vbird.org/somepaper/20050630-dns-2.pdf

但是他还不是照样很红火?

我想,是google根据判断把本来是一个站的内容分在了两个域名下。

说明这还是有问题的,我上vbird.org问一下站长vbird的想法如何?

也许,正如:SEO每日一帖的zac说的那样,我中了SEO的毒了?

如何分离个人信息,缓存动态页面(转帖)

下面是一个用于php中的静态缓存加入动态个人信息的方案,我觉得他的思路是可以借鉴的,就转帖在这里了。

正文

****************************************************************************

转自:(http://nio.infor96.com/archives/283

如何分离个人信息,缓存动态页面

肖理达 (KrazyNio AT hotmail.com), 2005.06.07, 转载请注明出处

一直想写一篇关于动态页面 cache 的文章,但每次?提笔?却又放弃,因为总是觉得准备得

还不够充分。今天埋头写下,只是希望对自己的工作做一些笔录。

1、问题起源

我们经常会在一个动态页面中加入很多个人信息,以 CMS 首页为例,用户登录之前显示登

录框,登录之后显示其用户名,并根据权限显示其可用模块的链接。由于每个用户登录之

后,显示出来的动态信息都是不一样的,所以这部分无法进行 cache,我们将这部分信息

定义为?个人信息?,它的特性是根据登录用户进行动态改变。

现在问题来了,就是一个 CMS 的首页,访问者的登录概率并不是百分百的,应该说有一大

部分人访问首页是没有登录的,这个时候的首页是一个公共的页面,没有任何个人信息,

或者说这时候首页的任何动态信息都是可以转换成静态的,也就是说这部分是可 cache 的

2、使用 JavaScript 分离个人信息

解决这个问题的方法有很多种,一种是将个人信息和其他信息进行分离,如在 CMS 首页中

加入一个外部的 JavaScript 文件,而这个文件的内容实际上是由 PHP 动态生成的。CMS

首页 index.php 代码片段:

<script language="JavaScript" src="/js/personal.php"></script>

?.

<script language=?JavaScript?>

document.write(sUser);

document.write(sLinks);

</script>

personal.php 代码片段:

<?php

session_start();

header(?Cache-Control: no-store, no-cache, must-revalidate?);

?>

sUser = ?<?php echo $_SESSION['USER']; ?>?;

sLinks = ?<?php echo addslashes($_SESSION['LINKS']); ?>?;

这种方法比较适合个人信息较少,易于集中显示的情况。通过 JavaScript 外挂代码实现

个人信息分离之后,personal.php 是永不 cache 的,这样也就可以放心地对 CMS 首页进

行 cache 了,具体的 cache 方法可采用 304 HTTP 头与 Cache_Lite 相结合的方式,这

在后边有详细代码示例。

3、选择性分离个人信息

一旦个人信息较多,很难对其进行分离的时候,上述方法实现起来就会比较麻烦了。接下

来介绍一种比较放宽的 cache 方式,就是只对用户未登录的 CMS 首页进行 cache,一旦

发现用户处于登录状态,则跳过 cache 部分,直接运行相关代码,我把这种方法称为?

选择性 cache
?。这种方法中,我们牺牲了一部分可 cache 的情况,但很大程度上提

高了个人信息的可扩充性,也就是说个人信息的多少、显示的位置等等都不再受到限制,

这是值得的,毕竟修改服务端代码要比修改大量的 JavaScript 代码要来得方便,而且

JavaScript 的调试也会比较麻烦。

分析一下这种 cache 方式,概要流程图如下:

image

代码片段如下:

<?php

session_cache_limiter(?must-revalidate?);

session_start();

if (empty($_SESSION['USER'])) { //未登录时才使用 cache

    ?.    //输出 cache

} else {

    //  直接输出页面内容,此条件下与未使用 cache 时一样

    $data =& get_data();

    echo $data;

}   //end if

?>

这里需要说明的一点是,由于 PHP 在使用 SESSION 时,php.ini 中默认设置的

session.cache_limiter 为 nocache,所以需要修改 cache_limiter,设置成

must-revalidate,使得客户端再次浏览当前页时必须发送相关 HTTP 头信息到服务器进行

验证,然后才决定是否加载客户端本地 cache。不要把客户端本地 cache 与服务器端

cache 搞混,之后的代码片段中会充分利用客户端 cache 和服务器端 cache 机制达到缓

存的目的。关于 must-revalidate,请参考 HTTP 规格说明书 RFC 2612 的 14.9.4 章节

上边的代码并不完整,接下来是更加深入的探讨客户端 cache 机制了,利用客户端 cache

,可以有效地减轻服务器端负载。首先了解一下 HTTP 头:Last-Modified 与

If-Modified-Since。简单的说,Last-Modified 与If-Modified-Since 都是用于记录页面

最后修改时间的 HTTP 头信息,只是 Last-Modified 是由服务器往客户端发送的 HTTP 头

,而 If-Modified-Since 则是由客户端往服务器发送的头,其工作原理图如下:

image

可以看到,再次请求本地存在的 cache 页面时,客户端会通过 If-Modified-Since 头将

先前服务器端发过来的 Last-Modified 最后修改时间戳发送回去,这是为了让服务器端进

行验证,通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回新的

内容,如果是最新的,则返回 304 告诉客户端其本地 cache 的页面是最新的,于是客户

端就可以直接从本地加载页面了,这样在网络上传输的数据就会大大减少,同时也减轻了

服务器的负担。想要详细查看 HTTP 头信息,可以在 Firefox 中安装 LiveHTTPHeaders

插件,安装完成之后按 Alt+L 就可以在 Sidebar 中看到了。

现在再来完善之前的 index.php 代码:

<?php

session_cache_limiter(?must-revalidate?);

session_start();

function &get_data()

{

    //此函数用于获取本页面的输出内容

    //?.

}   //end function

if (empty($_SESSION['USER'])) { //未登录时才使用 cache

    //====================================================

    //  1. 检查 HTTP 头是否符合 304 的条件

    //====================================================

    //get_last_modified() 函数需要另外单独实现,此函数用于获取服务器端 cache 文件的最后修改时间,可将时间戳保存在数据库中。

    $last_modified = get_last_modified();

    $headers = getallheaders();

    if (strtotime($headers['If-Modified-Since']) == $last_modified) {

        //  返回 304 并结束程序运行

        header('HTTP/1.1 304 Not Modified');

        exit;

    }   //end if

    header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $last_modified) . ' GMT');

    //====================================================

    //  2. 检查 cache 文件是否存在

    //====================================================

    require_once 'Cache/Lite.php';

    //  参数设置

    $options = array(

        'cacheDir' => './cache/',

        'lifeTime' => 86400, //最大 cache 一天时间

        'fileNameProtection'   => false //使用 CMS 自身提供的 id 作为名字

    );

    $cache = new Cache_Lite($options);  //创建 Cache_Lite 对象

    $id = md5($_SERVER['REQUEST_URI']); //生成对应于 cache 文件的 ID

    if ($data = $cache->get($id)) {   //存在 cache 文件,获取内容,直接输出

        echo $data;

    } else {

        $data =& get_data();

        echo $data;

        flush();

        $cache->save($data);    //保存 cache

    }   //end if

} else {

    $data =& get_data();

    echo $data;

}   //end if

?>

测试时可以使用 LivHTTPHeaders 插件,你将会看到第一次访问时是返回 200,第二次到

第N次访问时则返回了 304,而登录之后,则一直都返回 200,因为我们选择性 cache 之

后,对登录之后一律运行程序输出,而不使用 cache,如果之后需要对输出的个人信息进

行修改,只需要改函数 get_data() 即可,也避免了 JavaScript 的调试。

总结

除此之外,还有其它方法可以实现分离个人信息,缓存动态页面的目的。而且为了提高服

务器运行效率,还可以使用数据库 cache、Squid 反向代理等,如 ADOdb 的 cache。目前

用的比较多的 Drupal 应用的就是本文中提到的第二种方法。

参考资料

HTTP Caching & Cache-Busting for Content Publishers

Hypertext Transfer Protocol ? HTTP/1.1

PHP Anthology, Volume 2: Applications. Chapter 5: Caching

Caching Tutorial for Web Authors and Webmasters

Drupal 源代码

Comments RSS | Trackback URL

4 Comments on ?关于 Cache(4)?

By zeal. June 13th, 2005 at 3:25 pm

我们目前采用的是oracle cache server以及squid。对于不能cache的内容采取分目录存放

。在代码设计的时候就考虑可cache性。对于大量需要用户交互的内容,似乎cache的作用

不大。

By Nio. June 13th, 2005 at 5:02 pm

嗯,如果内容本身全都是个人信息的话或者必须登录才能浏览的页面,就用不到这种cache

方法了,需要看登录与不登录的概率比而定 🙂

By nc. July 17th, 2006 at 12:43 pm

感谢你文章的提示,非常不错.

By ahu. October 8th, 2006 at 5:10 pm

zeal的公司貌似有些money~

**************************************************************************

                                                           转载完毕

另一段静态页面计数代码:


<script language="javascript" src="/data/include/count.php?id=$id"></

script>

转摘自:(http://www.mephp.com/view.php?tid=1&id=44

JAVA学习日记页面静态化方案

JAVA学习日记页面静态化方案(借鉴了:http://www.agilejava.org/space/?233的 生成静态页面技术解决方案系列,见我的转帖:一个实现将JSP动态页面转为静态的方案(转帖)

1、首页和帖子页面静态化,帖子列表不静态化;

2、列表上的帖子用静态化链接;

3、隐私帖子页面不静态化;用户登录后用动态化链接,所以可以看到隐私帖子;

4、静态化时机:

  1)、发公开帖子;

  发公开目标:静态化目标和首页;

  公开日记:静态化日记、目标和首页;

  公开评论:评论日记:静态化日记、目标、首页;评论目标:静态化目标、首页;

  发私人日记:不作任何静态化;

  2)、修改公开帖子;

  修改目标(目标不能修改隐私属性):

  修改公开目标:目标、首页;

  修改私有目标:不作任何静态化;

  修改日记(日记可以修改隐私属性):

  修改公开日记,并且修改后仍是公开帖子:静态化日记、目标、首页;

  修改公开日记,但是修改后的日记是私有帖子:删除已经静态化日记,重新静态化目标、首页;

  修改私有日记,并且修改后仍是私有帖子:不作任何静态化;

  修改私有日记,但是修改后成了公开日记:静态化日记、目标、首页; 

  修改评论(评论的隐私属性与被它评论的目标或日记一致)

  修改公开目标的评论:静态化目标、首页;

  修改公开日记的评论:静态化日记、目标、首页;

  修改私有目标的评论:不作任何静态化;

  修改私有日记的评论:不作任何静态化;

  3)、删除帖子(私有帖子是不能被删除的);

  删除公开目标:删除目标会删除此目标下的评论和日记和日记的评论,所以要:删除已静态化的目标、删除已静态化的目标的日记、重新静态化首页;

  删除公开日记:删除日记会删除此日记下的评论,所以要:删除已经静态化的日记、重新静态化首页;

  删除公开评论:删除目标的公开评论:重新静态化目标、首页;删除日记的公开评论:重新静态化日记、日记的目标、首页;

 

  4)、静态化种类:

  手动静态化:由管理员执行手动全面静态化及维护工作:包括:对数据库和静态化文件储存目标扫描,重新静态化应该静态化的帖子;如果某个不应该静态化的私有目标或日记被静态化了则删除已静态化的文件,并且作下记录,分析原因;

  定时静态化:同手动静态化一样的功能,只不过由系统定时进行,比如每晚12:00点;

  帖子变动时的静态化:如上面的列表;

5、其它注意事项:

  1)、为了统一静态化页面和简要设计和增加系统灵活性,现对登录用户和游客用户(包括搜索引擎)的静态化作一区别:

  登录用户:全部用动态化,也就是说与现在动态化的系统没有区别;从各论坛和网站的统计情况来看:登录用户占全部用户的比例一般在5%左右,所以不会系统有什么大的影响;

  未登录用户(包括搜索引擎):首页和帖子全部用静态化,游客提交评论后通过Action的301跳转进入已静态化的最新页面,但是提交评论的表单已经静态化了,所以不能记住用户,这可以放在以后解决,同屏蔽垃圾留言的设计一起进行,可能会用<frame>内嵌表单来做。

  2)、类的设计:

  1个执行实际静态化的类:ToHtml.java;1个模拟游客访问,调用静态化的工具类:CallHtml.java;再增加一个静态化文件管理类:HtmlsManager.java,用于封装各种静态化时机的操作,包括:

  1>,提交帖子:doPostArt(),传入提交的帖子作为参数,即为doPostArt(ArticleInfo postedArt);

  2>,修改帖子:doEditArt(),传入修改前的帖子和修改后的帖子作为参数,即为:doEditArt(ArticleInfo oldArt, ArticleInfo newArt);

  3>,删除帖子:doDelArt(),传入被删除的帖子作为参数,即为:doDelArt(ArticleInfo);

  4>,检测是否相应静态化文件的方法:isExist(String phyFullName),传入系统路径的包含路径的全文件名作为参数;

  5>,删除一个相应静态化文件的方法:delete(String phyFullName),传入系统路径的包含路径的全文件名作为参数;

添加游客评论功能设计之测试计划

今天,添加游客评论功能设计所计划的功能已经基本实现。

1、实现过程中的改动:

  GuestArtInfo.java用原有的ArticleInfo.java代替;CookieManager.java因为所需要的代码少,另开一个类反而麻烦,功能直接写在了Action中;在util包中添加了一个处理解析存储在帖子正文头部的游客信息的工具类:GuestArtProcessor.java

2、一点心得:

  原来以为struts-config.xml中的“input="/disGoalContentAction.do"”只能用jsp文件,结果证明用*.do的路径也行,而且有时还必须如此。如下面:


        <action

            attribute="guestArtForm"

            input="/disGoalContentAction.do"

            name="guestArtForm"

            path="/postGuestArtAction"

            scope="request"

            type="com.learndiary.website.action.disgoal.PostGuestArtAction">

           

            <!--forward name="goalSuccess" path="/processGoalAction.do" /-->

           

            <!-- forward name="diarySuccess" path="/disall/disgoal/afterPostDiarySelect.jsp" /-->

            <forward name="goalSuccess" path="/toSendMailOfGoalAction.do" />

            <forward name="diarySuccess" path="/toSendMailOfGoalAction.do" />

            <forward name="isBackSubmit" path="/processGoalAction.do" />

            <forward name="isBackSubmit1" path="/disGoalContentAction.do" />

            <forward name="isBackSubmitGoal" path="/processGoalAction.do" />

            <forward name="adviceSuccess" path="/disGoalContentAction.do" />

            <forward name="adviceOfDiarySuccess" path="/disGoalContentAction.do" />

            <forward name="adviceOfGoalSuccess" path="/toSendMailOfGoalAction.do" />

            <forward name="messageSuccess" path="/main.do" />

            <forward name="failure" path="/disall/disgoal/disGoalContent.jsp" />

            <forward name="nonUser" path="/main.do" />

            <forward name="noParentArt" path="/main.do" />

        </action>

自己感觉有必要写个测试列表,进行逐项测试:

1,每项功能经过游客、注册用户、管理员的测试;每项功能在日记的评论和目标的评论中都要经过测试;

2,理想状态功能使用:

填写所有字段,无无效字符串。

3,用户信息为空,或只填用户名、邮件、网址其中一项或多项;

4,帖子内容或标题为空;

5,填写了字段,但是格式错误;

6,测试在其它页面游客发的帖子是否显示正常;

7,测试有游客发帖时的邮件发送内容是否正常;

8,测试有游客发帖时的RSS订阅内容是否正常。

9,传到网上公开测试;

例外:

1,因为软件暂时没有想到解决办法或麻烦,下列项暂时搁置:

1),网址格式过滤;

2),重复提交问题;

提交事件21,建了数据库表和bean,database 操作类

思路来自: 明确网站定位,增加学习日记目标分组功能

向开源社区提交了issue 21:

http://learndiary.tigris.org/issues/show_bug.cgi?id=21

The all different goals can be organized by group, in this way, user can get the

outline of a website which running LearnDiary.

Add some Top 10 statistical data of website, such as top 10 newly created

diaries, top 10 most posting diaries' user, etc..

今天完成了相关数据库表建立,一个bean模型,和bean模型的数据库存取类。延续原来的入门级设计方法,快速实现需要的功能。

还是以前的思路,软件应用为先。