深入研究Application和Session对象


  用ASP编写 虚构社区、网上购物等程序时,Application和Session对象 存在举足轻重的作用, 可以灵便 正当地 使用这两
个对象是 普及程序 品质的 要害 。下面让小编依据自己在这方面的 教训,向大家 深刻介绍一下ASP的这两个内建对象 。

  一、Application对象的成员概述

  Application对象成员包含Application对象的 集中、 步骤和事件 。

  ⒈Application对象的 集中

  Contents 集中:没有 使用元素定义的存储于Applicaiton对象中的全部变量的 集中

  StaticObjects: 使用元素定义的存储于Application对象中的全部变量 的 集中

  例:在default.asp中有如下赋值

  application("a")="a"

  application("b")=128

  application("c")=false

  则有contents 集中

  application.contents(1)="a" '也可写为application.contents("a")="a"

  application.contents(2)=128 '也可写为application.contents("b")=128

  application.contents(3)=false '也可写为application.contents("c")=false

  在此小编推举你在调用时 使用类如application.contents("a")的 步骤,由于这样更为直观,如果用序号来 示意的话则
要考量赋值的先后顺序 。

  ⒉Application对象的 步骤

  Contents.Remove("变量名"):从Application.Contents 集中中删除指定的变量

  Contents.RemoveAll() :把Application.Contents 集中中的全部变量删除

  Lock() :锁定Application对象,使得惟独目前的ASP页对内容能进行 拜访

  Unlock() :解除对Application对象的锁定

  例:在default.asp中:

  application("a")="a"

  application("b")=128

  application("c")=false

  response.write application.contents(1)&"
"

  response.write application.contents(2)&"
"

  response.write application.contents(3)&"
"

  response.write "After Remove b:"

  application.contents.remove("b")

  response.write application.contents(1)&"
"

  response.write application.contents(2)&"
"

  执行 后果:

  a

  128

  False

  After Remove b:

  a

  False

  如果要删除 集中中全部变量用application.contents.removeall即可,至于Lock和Unlock 步骤在实际中 时常用到,读
者也 比较 相熟,在此就不在累赘 。

  ⒊Application对象事件

  OnStart:第一个 拜访服务器的消费者第一次 拜访某一页面时 产生

  OnEnd :当最终一个消费者的会话已经 完毕而且该会话的OnEnd事件全部代码已经执行 结束后 产生,或最终一个消费者 拜访
服务器一段 工夫(普通为20分钟)后 依旧没有人 拜访该服务器产生 。

  想要定义application对象的OnStart和OnEnd事件里做什么需求将代码写在Global.asa这个文件里(下文有举例),并
且将该文件放在站点的根目录下(普通是Inetpubwwwroot)

  二、Session对象的成员概述

  Session对象的成员比Application对象多一项属性,即: 集中、属性、 步骤、事件

  ⒈Session对象的 集中

  Contents :没有 使用元素定义的存储于特定Session对象的全部变量的 集中 。

  StaticObject: 使用元素定义的、存储于Session对象中的全部变量的 集中 。

  例:在default.asp中有如下赋值

  session("a")="a"

  session("b")=128

  session("c")=false

  则有contents 集中

  session.contents(1)="a" '也可写为session.contents("a")="a"

  session.contents(2)=128 '也可写为session.contents("b")=128

  session.contents(3)=false '也可写为session.contents("c")=false

  ⒉Session对象的属性

  CodePage: 可读/可写 。整型 。定义用于在阅读器中显示页内容的代码页 。代码页是字符集的数字值,不同的语言 使用
不同的代码页 。例如,ANSI代码页为1252,日文代码页为932,简体中文代码页为936 。

  LCID : 可读/可写 。整型 。定义发送给阅读器的页面地域标识 。LCID是唯一地标识地域的一个国际 标准缩写,例如,
2057定义目前地域的货币符号是"£" 。

  SessionID: 只读 。长整型 。返回本会话的会话标识符 。每 缔造一个会话,由服务器自动 调配一个标识符 。 可以依据它
的值推断两个消费者是谁先 拜访服务器 。

  Timeout : 可读/可写 。整型 。为会话定义以分钟为单位的超时限定 。如果消费者在这个 工夫内没有刷新或 申请任何一个
网页,则该消费者产生的会话自动 完毕 。缺省值是20 。

以上属性在实际 利用中作用不大,而且 根本上不需求怎么 批改,这几个属性也没什么特殊的地方 。

  ⒊Session对象的 步骤

  Contents.Remove("变量名"): 从Session.contents 集中中删除指定的变量

  Contents.Removeall() : 删除Session.contents 集中中的全部变量

  Abandon() : 完毕目前消费者会话而且 取缔目前Session对象 。

  Session对象的Contents.Remove("变量名")和Contents.Removeall() 步骤与Application对象的 根本上没什么区别,为
协助 了解,大家 可以参照上面的例子将Application改为Session 。这里要 注明一下的是Contents.Removeall()和Abandon()
的区别,执行这两个 步骤都会 开释目前

  消费者会话的全部Session变量,不同的是Contents.Removeall()单纯地 开释Session变量的值而不终止目前的会话,而
Abandon()除了 开释Session变量外还会终止会话激发Session_OnEnd事件, 盼望大家 留神两者的区别 。

  ⒋Session对象的事件

  OnStart: 当ASP消费者会话产生时触发,一旦有任一消费者对本服务器 申请任一页面即产生该事件 。

  OnEnd : 当ASP消费者会话 完毕时触发,当 使用Abandon() 步骤或超时也会触发该事件 。

  这两个事件和Application的OnStart、OnEnd事件一样,也是必须放在Global.asa文件里,下
面就重点和大家探究一下这四个事件的 使用 。

  三、Global.asa

  ASP的Application和Session对象体现了 其余ASP内置对象所没有的 特色--事件 。每一个访客 拜访服务器时都会触发一
个OnStart事件(第一个访客会同时触发Application和Session的OnStart事件,但Application先于Session),每个访客
的会话 完毕时都会触发一个OnEnd事件(最终一个访客会话 完毕时会同时触发Application和Session的OnEnd事件,但
Session先于Application) 。

  OnStart和OnEnd这两个事件普通 利用在 虚构社区中统计在线人数、 批改消费者的在线离线状态等 。要具体定义这两个事
件,需求将代码写在Global.asa文件,并将该文件放在站点的根目录下(缺省是Inetpubwwwroot) 。另外,
Application和Session对象规定了在OnEnd事件里除了Application对象外 其余ASP内置对象(Response、Request、
Server、Session...)一律不能 使用 。以下举一个 虚构社区统计在线人数的例子来 注明如何 使用这两个事件 。

  文件 注明:

  global.asa 位于d:Inetpubwwwroot目录下

  default.asp 位于d:Inetpubwwwroot目录下, 虚构社区登录页面

  login.asp 位于d:Inetpubwwwroot目录下,用于检测消费者输入的消费者名及密码

  index.asp 位于d:Inetpubwwwroot目录下, 虚构社区首页

  bbs.mdb 位于d:Inetpubwwwroot目录下,存储消费者信息的数据库

  数据库(ACCESS) 构造:

  ===bbs表===

  id 消费者ID,长整型

  name 消费者名,文本型

  code 密码,文本型

  online 在线状态,是/否

 
  ===global.asa===

  <script LANGUAGE="VBScript" RUNAT="Server">

  Sub Application_OnStart

  application("online")=0

  End Sub

  sub Application_OnEnd

  nd Sub

  Sub Session_OnStart

  End Sub

  Sub Session_OnEnd

  if session.contents("pass") then '推断是不是为登录消费者的Session_OnEnd

  application.lock

  application("online")=application("online")-1

  application.unlock

  end if

  End Sub

  </script>

  ==============

  ===login.asp===

  ......'密码验证,衔接数据库,检测消费者输入的消费者名及密码是不是正确

  if 密码验证通过 then

  session("name")=rs("name")

  session("id")=rs("id")

  session("pass")=true

  else

  rs.close

  conn.close

  response.write "密码 舛误!"

  response.end

  end if

  application.lock

  application("online")=application("online")+1

  conn.Execute ("update bbs set online=1 where id="&session("id"))'将消费者的状态设为在线

  application.unlock

  rs.close

  conn.close

  response.redirect "index.asp" '初始化数据后跳转到社区首页

  ===========

  在本例中,用application("online")变量记录已经登录社区的在线人数,由于一旦有消费者 拜访服务器而 无论消费者是不是
登录,都会产生OnStart事件,所以不能在OnStart事件里使Applicaiton("online")加一 。由于 无论是不是是登录消费者的会话
完毕都会产生OnEnd事件(如果有访客 拜访了服务器但并不登录社区,他的会话 完毕后也会产生OnEnd事件),所以在
Session_OnEnd事件里用了句if语句来推断是不是为已登录消费者的OnEnd事件,如果是才将在线人数减一 。

  这只不过一个统计在线人数的 方便例子,关于一个 完全的 虚构社区来说,仅仅统计有多少人在线是不够的,在本例中数
据库里有个online字段是用来记录消费者的在线状态,消费者登录的时候,在login.asp里将online设为1,但消费者离线时并没
有将online设为0,要完善它,就要 批改一下Session_OnEnd事件,在该事件里将online设为0 。

  ===global.sas===

  <script LANGUAGE="VBScript" RUNAT="Server">

  Sub Application_OnStart

  application("online")=0

  set application("conn")=Server.CreateObject("ADODB.Connection")

  application("db")=Server.MapPath("bs.mdb") '此处最好 使用绝对路径bs.mdb,下文有 详尽介绍

  End Sub

  sub Application_OnEnd

  set application("conn")=nothing

  End Sub

  Sub Session_OnStart

  End Sub

  Sub Session_OnEnd

  if session.contents("pass") then '推断是不是为登录消费者的Session_OnEnd

  application("con").open ="driver={Microsoft Access Driver (*.mdb)};dbq="&application("db")

  application.lock

  application("online")=application("online")-1

  application("con").Execute ("update friends set online=0 where id="&session.contents("id"))

  application.unlock

  application("con").close

  end if

  End Sub

  </script>

  ==============

  至此, 完全的代码已经 实现了 。由于在Application和Session的OnEnd事件里不能 使用Server对象,所以要将数据库的
衔接及数据库在服务器上的物理地址(d:inetpubwwwrootbs.mdb)存储在application变量中,并在
Application_OnStart事件中预先 解决 。同理,在Session_OnEnd事件中不能用session("pass")来 接替session.contents
("pass")(以下有详尽 注明) 。

  四、本文实例中值得引起 留神的两点

  ⒈OnEnd事件里的session.contents

  刚开始接触global.asa的朋友 时常会将上面Session_OnEnd事件里的

  if session.contents("pass") then 写成

  if session("pass") then,

  这样的话系统不会 揭示 舛误,然而永远也不会执行then后面的内容,这是由于在OnEnd事件里禁止 使用Session对象,
然而 可以用Session对象的 集中来调用session变量 。由于IIS并没 揭示任何 舛误信息,所以小编曾经在这上面 浪费了众多时
间 。在此 盼望大家引 认为鉴!

  ⒉Application_OnStart事件里用Server.MapPath猎取数据库的物理地址时应 使用绝对地址为了 注明这个问题,大家可
以做个 试验:将上面Application_OnStart事件里的

  application("db")=Server.MapPath("bs.mdb")改为:

  application("db")=Server.MapPath("bbs.mdb")

而后在d:inetpubwwwroot目录下 构建一个test子目录,写一个temp.asp在test目录里 。

  ====test.asp====

  <%response.write application("db")%>

  ================

再将temp.asp拷贝一份放在根目录下(d:inetpubwwwroot) 。用记事本 打开global.asa,再 打开两个阅读器,阅读器A
输入地址http://localhost/temp.asp,按回车,将在阅读器上输出:

  d:inetpubwwwrootbs.mdb

而后,在记事本的窗口上点"文件"菜单,选" 保留"(使global.asa的 批改 工夫转变,从而使IIS重启动全部服务),再在浏
览器B输入地址http://localhost/test/temp.asp,按回车,在阅读器上输出的是:

  d:inetpubwwwrootestbs.mdb

global.asa文件 固然是放在站点根目录下,然而如果在server.mappath中 使用的是 绝对地址,而触发Application_OnStart
事件的消费者第一次 拜访的页面又不是属于根目录的话,得到数据库的物理地址将不会是 期冀的 后果, 盼望大家要特殊小
心 。