zhangsenwei

张森炜的博客

联系 管理
  19 Posts :: 8 Stories :: 55 Comments :: 0 Trackbacks
这次我们来看一下session的使用,那么我们就通过一个统计网站在线用户这个例子来开始我们今天的话题吧。

    我们上次说了当一个客户端第一次访问网站时,服务器就会为这个客户端创建一个session,那么我们可以在某一时刻通过session的存活数量知道当前有多少客户端在线,那么问题是我们怎么才能知道某一时间内有多少个session存活呢?我们可以自己写一个累加器帮我们完成,当一个新的客户端访问服务器时就要创建一个新的session这是当我们session被创建时我们将计数器加1,反之如果一个session长时间没有用超出了设置的超时时间session就会被销毁,我们就在它销毁的时候将计数器减1,这样我们就可以知道当前有多少人在线了。其实我们可以通过上面的这个例子看出我们在对session的创建和销毁进行监听,没错,这个例子正是session的监听器。那么我们来看一下代码如何写。

首先我们创建一个主页 index.jsp

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<html>

  
<head>

     
<title>Session监听</title>

   
</head> 

  
<body>

    
<FORM name="form" method="GET" action="success.jsp">

            
<P>       Name:    

             
<INPUT type="text" name="name">  

            
</P>

            
<P>

                  password:
<INPUT type="password" name="pwd">

            
</P>

            
<P>                           

                
<INPUT type="Reset" name="button2" value="重置"> 

                 
<INPUT type="Submit" name="button1" value="提交" />

            
</P>

</FORM> 

</body>

</html>

        上面这个index.jsp 页面的作用是让我们点击提交按钮后进入 success.jsp 页面中,而在success.jsp中可以看到当前在线人数的数量,当然要在这里注意一点的是当我们访问index.jsp时服务器端的session就已经被创建了,而不是当我们点击完提交按钮后才创建的。也就是说当我们已打开index.jsp页面时我们的计数器就已经加1了,而点击提交按钮只是将我们的计数器中的值取出来。

我们再去创建一个包,包的名字叫:listener

我们再在listener包中创建一个类,名字是:SessionLis

SessionLis源码如下:

 

package listener;

import javax.servlet.ServletContext;

import javax.servlet.http.HttpSessionEvent;

import javax.servlet.http.HttpSessionListener;

public class SessionLis implements HttpSessionListener{

    
//累加器累计在线人数

       
static int num=0;

    
//当session创建时,调用此方法

       
public void sessionCreated(HttpSessionEvent arg0) {

              
/*

               * 获取Servlet上下文对象,上下文对象是全局

               * 的类似于Application的功能

               
*/


              ServletContext application 
= arg0.getSession().getServletContext();

              
/*

               * 应为此方法只有创建session时才会被调用,

               * 程序执行到此表示有一个新的session对象

               * 产生了,所以要将累计器加 1

               
*/


              
++num;

              
/*

               *将累加器更新后的数据存放到上下文中

               
*/


              application.setAttribute(
"num",num+"");

              
/*

               *为session设置超时时间

               *但这里需要注意即使超时时间到了session对象不一定

               *会被销毁,应为什么时候销毁不是由我们人为决定的

               *是由容器Tomcat所决定的。

               
*/
         

              arg0.getSession().setMaxInactiveInterval(
100);         

       }


        
//当session销毁时调用此方法

       
public void sessionDestroyed(HttpSessionEvent arg0) {

              System.out.println(
"bbb");

              
/*

               * 获取Servlet上下文对象,上下文对象是全局

               * 的类似于Application的功能

               
*/


     ServletContext application 
= arg0.getSession().getServletContext();

              
/*

               * 应为此方法只有销毁session时才会被调用,

               * 程序执行到此表示有一个session对象被

               * 销毁了,所以要将累计器减 1

               
*/


              
--num;

              
/*

               * 将累加器更新后的数据存放到上下文中

               
*/


              application.setAttribute(
"num",num+"");

       }


}


 

    上面这个类的作用,上看过以后基本都清楚了主要使用来监听session的创建与销毁的,有人又会问老师,那么是不是我随便写一个类让它实现HttpSessionListener接口就可以直接对session进行监听了,当然不是。既然我们要监听我们就要通知Tomcat容器让它知道呀所以我们还需要在web.xml中进行注册一下这样我们的Tomcat容器就知道了。我们打开web.xml文件修改代码:

 

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"

    xmlns
="http://java.sun.com/xml/ns/j2ee"

    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation
="http://java.sun.com/xml/ns/j2ee

    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
>

 
<listener>

       
<listener-class>

            listener.SessionLis

       
</listener-class >

 
</listener >

</web-app>

下面我们创建刚才在index.jsp中提到过的 success.jsp页面。

success.jsp源码:

 

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<html>

    
<head>

        
<title>My JSP 'success.jsp' starting page</title>

        
<script type="text/javascript">

   
function aa()

   
{

       frm1.action
="destroy.jsp";

       frm1.submit();

    }


</script>

    
</head>

 

    
<body>

        
<%=application.getAttribute("num")%>

        
<p>

        
<FORM name="frm1" method="GET">

            
<P>

                
<INPUT type="Button" onclick="aa()" name="button4" value="下线">

            
</P>

        
</FORM>

        
</P>

        
<P></P>

    
</body>

</html>

 

    上面这段代码中出现了一段javascrit代码里面有一个function名字叫 aa 这段代码的功能是当用户点击下线按钮时,调用这段脚本,将本页面的请求提交到destroy.jsp页面,这个页面是用来销毁session 。在上面的代码中还出现了

<%=application.getAttribute("num")%>  因为我们在监听器类中将计数器存放到了application中我们要显示存放内容只有从application中将其num的值取出。有些同学又问了问什么你不将计数器的值存放到session中而存放到application我们一起来想一下,我们要显示的在线人数是让所用用户看的而session只是针对于一个客户端的,如果我们用session保存,我们就不能够让所用用户看见,只有application中的值是整个web应用程序的,所以我们将其值保存到了application中。

下面我们再来创建一个destroy.jsp页面用来销毁session。

destroy.jsp源代码:

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<P>

 您现在已下线! 
</P><P> </P>

 
<%session.invalidate(); %>

    上面的代码中<%session.invalidate(); %>表示我们让当前session销毁。

有些同学又会问,老师不是session有自己的过期时间吗?为什么还要我们去调用方法让它销毁呢?我们大家都去过126、163 新浪、雅虎的信箱,当我们登陆进去以后都会发现有一个按钮“安全退出”为什么呢,其实我们上面已经说了在监听器SessionLis类中我在session的创建方法中的最后一句代码上面写了一句注释:

/*

               *为session设置超时时间

               *但这里需要注意即使超时时间到了session对象不一定

               *会被销毁,应为什么时候销毁不是由我们人为决定的

               *是由容器Tomcat所决定的。

               */         

    我们假设一下如果张三在网吧上网进入了自己的信箱,但是刚上了3分钟就去新浪网了,有过了5分钟张三走了,没有关闭浏览器,这时由于张三登陆的session没有销毁所以后来的李四就可以用刚才张三打开的浏览器后退而不需密码的进入张三的信箱。而服务器有没有办法检测到张三什么时候离开的,张三离开了而服务器端的session过期时间没有到session没有销毁,即使时间到了session也不会马上销毁还要有容器决定,这样就会很不安全,所以设置了一个安全退出,而这个方法可以马上可以让当前的session销毁掉,以保障当前用户的信息安全。这也就是为什么各个信箱设置“安全退出”的原因了。

    好了,在session的使用中有个很常用的方法  session.setAttribut(key,valueObject)当我们想为当前用户设置或保存某种状态时用这个方法。在这句代码中两个参数,因为我们可以为当前session 中存放多个值,而我们如何取值呢?我怎么知道取得是不是我想要的值呢?所以就用一个key键来进行标示,一个key对应的一个值,比如我现在向当前session中存放了3个值:

 

  session.setAttribut(“1”,”123”);

  session.setAttribut(“age”, 
new Integer(24));

  session.setAttribut(“qhit”,”山西太原清华IT学习认证中心”);

 

    如果我现在想取出值为“山西太原清华IT学习认证中心”的内容,如何来取呢?我们可以通过 session.getAttribut(“qhit”);  来获取键为qhit所对应的值“山西太原清华IT学习认证中心”。

好了,通过这个例子,相信大家应该对session的应用和它的作用域有一定的了解,如果还有什么不清楚的可以留言。(session的介绍结

posted on 2008-06-21 08:47 张森炜 阅读(736) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: