大家在浏览网页时经常会遇到各种各样的新闻列表。网站的浏览者可能对新闻列表本身并不在意,关心的只是列表中抢眼的标题,但对于CMS和网站的开发人员来说,则大有学问。下面我们就此问题展开探讨,希望有CMS开发和管理经验的朋友多提意见。
通常来讲,新闻列表从发布的方式上可以分为三类:
1.纯静态发布
2.纯动态发布
3.动/静混合发布
下面分别简单介绍这三种方式:
1.纯静态发布
这种发布方式是吧数据库中的新闻内容全部发布为静态的HTML文件。比如,数据库中有100条记录,新闻列表每页最多显示20条,则采用纯静态发布方式,根据这100条记录将发布出5个静态的HTML页面,分别显示从第1-20,第21-40,第41-60,第61-80和第81-100条记录,并分别有各自硬编码在页面上的分页导航代码。
这样做的优点在于,可以完全通过Http服务器(如Apache、IIS)访问,而不需要像动态页面那样需要实时访问数据库,减轻了数据库的负担,并且提高了相应速度。
同时这种方式的缺点也是明显的,那就是生成静态页面的数量与数据量成正比。数据越多,生成的静态页面的数量也就越多。试想一下,有数万条记录的新闻频道要发布列表,每次更新新闻,哪怕只有一条更新,要刷新整个列表,将生成数千个静态页面!
所以,纯静态新闻列表发布比较适用于内容数量较少的情况。通常如果每次只生成几十页,还是可以接受的。
2.纯动态发布
这种发布方式与纯静态的发布方式正好相反。实际上这种方式已经不是纯粹意义上的“发布”了,它只是通过某种动态页面技术(如Asp,Jsp,Php等),通过实时访问数据库的方式,动态的生成新闻列表和分页导航。只需要一个页面,就可以完成整个新闻列表的分页显示。
这种方式的优点在于,可以避免大量的磁盘读写,只有一个页面即可解决问题。
缺点在于这种方式较第一种方式大大增加了数据库服务器的负担,特别是当访问量激增时,有可能会出现响应速度变慢甚至是无法访问的情况。
由此可见,如果新闻列表长度较短,且访问量较大时,可以采取纯静态发布的方式,如果新闻列表长度较长且访问量可承受时,则可采用纯动态的方式。
但是,当新闻列表长度较长,且访问量很大时,上述两种方式就都不适用了。对于大型综合性网站来说,这种情况是普遍的。在这种情况下,一个频道的新闻列表就有几千页,首先不能采取纯静态的发布方式;同时,对于新闻列表的前几页或几十页(也就是最近更新的部分)访问频率也很高。而且这些列表通常会成为网络爬虫频繁光顾的对象,而且还会有一些其他人通过编写程序高强度地疯狂扒取内容,造成某一时段的流量异常。在这种情况下,采用纯动态页面也是有问题的。
因此,在这种情况下,引出第三种解决方案:
3.动静混合新闻列表
针对刚才提出的问题,动静混合列表采用了部分静态、部分动态的发布方式。也就是说,根据正常浏览者的习惯,他们比较关心最近发生的新闻。因此,整个新闻列表的前面一小部分是被访问比较频繁的,因此采用静态发布的方式;而随着时间的推移,距离当前时间越远的新闻时效性越差受关注就越低,访问量也较小,因此采用静态发布分方式。这样做,即解决了大访问量情况下数据库的负载问题,同时也避免了大批量生成静态页面的问题。
下面就具体介绍一下如何通过Apache的高级SSI特性,结合JSP技术实现动态和静态页面混合的新闻列表发布。
要实现这一功能,需要编写以下JSP页面:
(1)version.jsp
(2).list.jsp
(3).publish.jsp
version.jsp中保存了当前发布的版本,由CMS生成。它标记了当前全部内容的版本。每当内容发生发生变化时,就要重新发version.jsp。
version.jsp的内容很简单:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%request.setAttribute(version,System.currentTimeMillis());%>
实际上就是向request中设定一个版本号。这个版本号可以根据自己的规则生成。在这里使用系统当前毫毫秒数作为版本号。
list.jsp负责动态生成新闻列表,包括分页导航。它既用于显示后半部分的动态列表,也是生成前面静态列表页面的模板那。
publish.jsp每次执行的时候,根据事先的设置,访问list.jsp获得前n页的页面代码。实现方式比较简单,可以通过URL打开httpConnnection读取就行了。拿到页面代码后,就直接写成静态文件,仅此而已。但是,如果新闻列表没有被更新就生成静态页面,就很浪费了。因此,需要在publish.jsp中将version.jsp引入:
<jsp:include page="/jsp/version.jsp"/>
同时,还要在本地保存一个本地版本:
<%!
private static String version="0";
%>
然后在执行时进行判断:
String globalVersion=(String)request.getAttribute("version");
if(globalVersion!=null && !globalVersion.equals(version)){
version=globalVersion;
.....(访问list.jsp,执行静态页面发布的代码)
}
这就是version.jsp,list.jsp和publish.jsp三个动态页面的作用和相互调用关系。
但是只有这三个页面还不行,因为访问者不知道在何时访问的是静态页面,在何时访问的是动态页面。必须把从静态
到动态的切换封装起来,这就需要使用Apache的高级SSI特性。
使用index.shtml作为整个列表的封装页。在index.shtml中,首先要引入publish.jsp,也就是说,要首先判断版本,
决定是否要生成新的静态页面:
<iframe src="publish.jsp" width="0" height="0"></iframe>
之所以用iframe,是为了避免一旦publish.jsp发生错误,把错误信息直接打印在页面上。
接下来,就是编写SSI代码:
//初始化页号变量
<!--#set var="p" value="1" -->
//如果在请求参数中指定了页号(如index.shtml?p=3),将请求参数中的页号赋给变量
<!--#if expr="$QUERY_STRING_UNESCAPED=/^p=([0-9]+).*/" -->
<!--#set var="p" value="$1" -->
<!--#endif -->
//判断页号范围,如果在0-20之间(由于采用字符串正则匹配,所以分别匹配了0-9,10-19和20),则包含静态页面
<!--#if expr="$p=/^[0-9]$/ || $p=/^[1][0-9]$/ || $p=/^20$/" -->
<!--#include virtual="l_$p.html" -->
<!--#else -->
//否则,包含动态页面
<!--#include virtual="/resource/jsp/list/zjzx_list.jsp?p=$p&key=SCIENCE-2009-07-42214245313E35W1F3AS5FD43SDAF135F" -->
<!--#endif -->
如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛