| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1607 人关注过本帖
标题:[原创]动网论坛源代码解读及其向JSP的移植——第二章,探索index.asp
只看楼主 加入收藏
京山游侠
Rank: 1
等 级:新手上路
帖 子:96
专家分:0
注 册:2006-2-12
收藏
 问题点数:0 回复次数:4 
[原创]动网论坛源代码解读及其向JSP的移植——第二章,探索index.asp

对于ASP程序来说,我们首先阅读的应该是Global.asa,因为这个文件中定义了在服务器启动和关闭时的动作以及每一个客户开始会话和结束会话时的动作。
但是,DVBBS没有Global.asa,所以,我们可以直接跳到它的入口点——index.asp——了。

该文件的一开头包含如下的文件:
<!--#include file="conn.asp"-->
<!--#include file="inc/const.asp"-->
<!--#include file="inc/dv_clsother.asp"-->

而inc/const.asp文件中还有一句包含:
<!--#Include File="Dv_ClsMain.asp"-->
也就是说,我们在阅读index.asp之前,还要阅读这四个被包含的文件。打开这四个文件一看,我的妈呀,几千行代码,吓死我了。

其实不用害怕,我们完全不用逐行研究这四个文件,因为这四个文件中主要是定义了一些全局的变量和类,而且conn.asp里面主要是管理和数据库的连接。对于这些变量和类,以及类的实例,我们可以在以后碰到的时候再到这四个文件中去找。但是,对于每碰到一个变量,我们都需要确定它的作用域,是Page范围的,还是Session范围的,还是Application范围的?

好了,下面可以开始进入index.asp了,打开一看,我的天,代码也不少啊。不用怕,其实index.asp的主要逻辑只有如下几行:
Const CachePage=false ''''''''是否做页面缓存
Const CacheTime=60 ''''''''缓存失效时间
Dim XMLDom,page,TopicMode,Cmd

If Request("w") = "1" Then
Passport_Main()
Response.End
End If

If (Not Response.IsClientConnected) and Dvbbs.userid=0 Then
Session(Dvbbs.CacheName & "UserID")=empty
Response.Clear
Response.End
Else
If Request("action")="xml" Then
Showxml()
Else
Main()
End If
End If

这几行的逻辑是这样的:
首先,定义几个变量,然后判断Request("w")是否为1,如果是的话,就执行Passport_Main()函数。说实话,我也不知道Passport_Main()函数是干什么的,因为我不知道什么时候才会给index.asp传递w=1这样的参数,可能要等到仔细阅读了Main()函数才会有答案吧。
下面的if(Not Response.IsClientConnected)语句是ASP开发中常用的一个技巧,就是判断浏览器是否和服务器有连接,为什么要用这个技巧呢?大部分情况下是防止用户还没有等待页面下载完就关闭浏览器。所以,这一句的意思是,如果用户关闭浏览器,就将这个用户的缓存清空,这里的缓存是Session范围的,以Dvbbs.CacheName加上UserID来标识。
关于Dvbbs对象,是在Conn.asp中定义的:
Set Dvbbs = New Cls_Forum
而Cls_Forum类在inc/dv_ClsMain.asp中定义,其中的CacheName成员如下初始化:
CacheName="DvCache" ''''如果一个虚拟目录或站点开多个论坛,则每个要错开,不能定义同一个名称
关于Dvbbs.UserID的初始化,我们可以在Cls_Forum的构造函数中找到
UserID = Trim(Request.Cookies(Forum_sn)("UserID"))
由此可见,UserID是从用户的Cookies中获得的

而Forum_sn是这样初始化的:
Forum_sn="DvForum" ''如果一个虚拟目录或站点开多个论坛,则每个要错开,不能定义同一个名称

如果用户没有关闭浏览器,那么就该显示首页了,如果用户是这样访问的首页:
http://localhost/MyOpenBBS/index.asp&action=xml
那么,调用Showxml()函数,显示的是一个XML文档,你可以这样访问编程中国的首页看看:
http://www.bc-cn.net/bbs/index.asp?action=xml
如果用户是按照常规模式访问首页,则调用Main()。

OK,将我们的注意力转移到Main()函数中来吧。

搜索更多相关主题的帖子: 源代码 JSP index asp 
2006-06-14 20:30
京山游侠
Rank: 1
等 级:新手上路
帖 子:96
专家分:0
注 册:2006-2-12
收藏
得分:0 
Sub Main()
''载入模板
Dvbbs.LoadTemplates("index")
If Dvbbs.BoardID=0 Then ''如果BoardID没有传入,则显示主页
Dvbbs.Stats=Replace(template.Strings(0),"动网先锋论坛",Dvbbs.Forum_Info(0))
Response.Write Dvbbs.mainhtml(18) ''显示主要的HTML内容
Dvbbs.Nav() ''调用Nav函数
Dvbbs.ActiveOnline() ''调用ActiveOnline函数
GetForumTextAd(0) ''调用inc/dv_ClsOther.asp中的GetForumTextAd函数,得到文字广告位的内容
BoardList() ''显示版面列表
Else ''否则,显示某一个版面的内容
Chk_List_Err()
TopicMode=0
If Request("topicmode")<>"" and IsNumeric(Request("topicmode")) Then TopicMode=Cint(Request("topicmode"))
If Dvbbs.Board_Setting(43)="0" Then
Dvbbs.Stats=Dvbbs.LanStr(7)
Else
Dvbbs.Stats=Dvbbs.LanStr(8)
End If
Response.Write Dvbbs.mainhtml(18)
Dvbbs.Nav()
Dvbbs.ActiveOnline()
Dvbbs.Head_var 1,Application(Dvbbs.CacheName&"_boardlist").documentElement.selectSingleNode("board[@boardid=''"&Dvbbs.BoardID&"'']/@depth").text,"",""
GetForumTextAd(1)
BoardList()
Page=Request("Page")
If ( Not isNumeric(Page) )or Page="" Then Page=1
Page=Clng(Page)
If Page <1 Then Page=1
If Dvbbs.Board_Setting(43)="0" Then
topicList()
End If
End If
Dvbbs.Footer ''显示页脚的信息,包括该教本执行时间,总共几次数据查询等等
End Sub

相濡以沫,不如相忘于江湖
2006-06-14 20:31
京山游侠
Rank: 1
等 级:新手上路
帖 子:96
专家分:0
注 册:2006-2-12
收藏
得分:0 
下面,我们再来总结一下index.asp页面执行过程中调用了哪些方法和函数,以便我们逐个进行分析。
conn.asp中有这两句:
Set Dvbbs = New Cls_Forum
Set template = New cls_templates

所以我们应该先分析Cls_Forum的构造函数和Cls_Templates的构造函数
inc/Const.asp中有如下代码:
Set MyBoardOnline=new Cls_UserOnlne
Dvbbs.GetForum_Setting
Dvbbs.CheckUserLogin

所以我们紧接着要分析Cls_UserOnlne的构造函数,Cls_Forum的GetForum_Setting方法,Cls_Forum的CheckUserLogin方法
再然后,就是Main函数里面的几个方法了。

此外,Conn.asp中还有一个ConnectionDatabase()函数,用来连接数据库。关于数据库连接的管理,我们将在下一章讨论。

下面,我们来看Cls_Forum的构造函数
Private Sub Class_Initialize()
Forum_sn="DvForum" ''如果一个虚拟目录或站点开多个论坛,则每个要错开,不能定义同一个名称
CacheName="DvCache" ''如果一个虚拟目录或站点开多个论坛,则每个要错开,不能定义同一个名称
If Not Response.IsClientConnected Then
Session(CacheName & "UserID")=empty
Set Dvbbs=Nothing
Response.End
End If
IsUserPermissionOnly = 0
IsUserPermissionAll = 0
ShowErrType = 0 ''错误信息显示模式
SqlQueryNum = 0
Reloadtime=28800
IsTopTable = 0
VipGroupUser = False:IsSearch=False:Cls_IsSearch=False
Vipuser = False:Boardmaster = False
Superboardmaster = False:Master = False:FoundIsChallenge = False:FoundUser = False
BoardID = Request("BoardID")
If IsNumeric(BoardID) = 0 or BoardID = "" Then BoardID = 0
BoardID = Clng(BoardID)
MemberName = checkStr(Trim(Request.Cookies(Forum_sn)("username")))
MemberWord = checkStr(Trim(Request.Cookies(Forum_sn)("password")))
UserHidden = Trim(Request.Cookies(Forum_sn)("userhidden"))
UserID = Trim(Request.Cookies(Forum_sn)("UserID"))
If IsNumeric(UserHidden) = 0 or Userhidden = "" Then UserHidden = 2
If IsNumeric(UserID) = 0 Or UserID="" Then UserID=0
UserID = Clng(UserID)
UserTrueIP = getIP()
IP_MAX=0
Dim Tmpstr
Tmpstr = Request.ServerVariables("PATH_INFO")
Tmpstr = Split(Tmpstr,"/")
ScriptName = Lcase(Tmpstr(UBound(Tmpstr)))
ScriptFolder = Lcase(Tmpstr(UBound(Tmpstr)-1)) & "/"
MemberClass = checkStr(Request.Cookies(Forum_sn)("userclass"))
Page_Admin=False
If InStr(ScriptName,"showerr")>0 Or InStr(ScriptName,"login")>0 Or InStr(ScriptName,"admin_")>0 Then Page_Admin=True
sendmsgnum=0:sendmsgid=0:sendmsguser=""
''模拟HTML部分开始
Is_Isapi_Rewrite = 0
If Is_Isapi_Rewrite = 0 Then ModHtmlLinked = "?"
ArchiverType = 0
If InStr(ScriptName,"indexhtml.asp") > 0 Then
iArchiverUrl = Lcase(Request.ServerVariables("QUERY_STRING"))
If iArchiverUrl <> "" Then
ArchiverUrl = iArchiverUrl
iArchiverUrl = Split(iArchiverUrl,"_")
If iArchiverUrl(0) = "list" And Ubound(iArchiverUrl) = 5 Then
If IsNumeric(iArchiverUrl(1)) Then
ArchiverType = 1
BoardID = Clng(iArchiverUrl(1))
End If
End If
End If
End If
''模拟HTML部分结束
''Response.Write Server.MapPath("index.asp")
''response.end
End Sub

由此可见,该段代码主要是设置一些全局变量,为以后的显示做准备,这里最重要的就是通过客户的Cookie得到用户的信息。
此外,这里所有的变量,包括Dvbbs对象本身,都只是Page范围的,因为它们既没有放到Session中,也没有放到Application中。

Cls_Templates没有构造函数,不用研究了。

相濡以沫,不如相忘于江湖
2006-06-14 20:31
京山游侠
Rank: 1
等 级:新手上路
帖 子:96
专家分:0
注 册:2006-2-12
收藏
得分:0 

紧接着,我们分析Cls_UserOnlne类的构造函数,发现其中调用了RefreshOnlineNum()函数,而RefreshOnlineNum()函数中调用了Dvbbs.Execute

紧接着,我们跟踪至Cls_Forum的Execute方法:
Public Function Execute(Command)
If Not IsObject(Conn) Then ConnectionDatabase
If IsDeBug = 0 Then
On Error Resume Next
Set Execute = Conn.Execute(Command)
If Err Then
err.Clear
Set Conn = Nothing
Response.Write "查询数据的时候发现错误,请检查您的查询代码是否正确。"
Response.End
End If
Else
If ShowSQL=1 Then
Response.Write command & "<br>"
End If
Set Execute = Conn.Execute(Command)
End If
SqlQueryNum = SqlQueryNum+1
End Function
在这段代码中,标记成不同颜色的两句很重要,第一句就是使用我们前面提到的ConnectionDatabase来创建连接,第二句就是把数据查询的次数加一,我们在每一个页面的最底下看到的总共执行了多少次查询,就是由这一句生成的了。

最后,我们再看了一眼Cls_Forum类的GetForum_Setting方法,发现里面调用了UpdateForum_Info,LoadBoardList(),Loadstyle(),这三个函数都是要从数据库中获取数据的,而他们获取数据的方法,无一例外都是通过调用Execute方法进行。

根据前面对Execute方法的分析,我们可以得出结论,该论坛采用的数据库连接管理策略是:每次需要更新数据的时候,创建连接,而且该函数中没有调用Conn.Close(),又而且Conn变量和Dvbbs对象都是页面范围的,所以,对于每一个页面,最多创建一次连接,页面关闭的时候关闭连接


相濡以沫,不如相忘于江湖
2006-06-14 20:32
xiaodan223
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2006-9-20
收藏
得分:0 
2006-09-20 18:06
快速回复:[原创]动网论坛源代码解读及其向JSP的移植——第二章,探索index.asp
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.030854 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved