|
会话跟踪是一种灵活、轻便的机制,它使在页面上的状态编程变为可能。http是一种无状态协议,每当用户发出请求时,服务器就做出响应,客户端与服务器之间的联系是离散的、非连续的。当用户在同一网站的多个页面之间转换时,根本无法知道是否是同一个客户,会话跟踪就可以解决这个问题。当一个客户在多个页面间切换时,服务器会保存该用户的信息。 在服务器上,通过为在站点上的用户创建一个会话对象保存该用户的信息。当用户第一次访问站点时,分配给用户一个会话对象和一个单独的会话id,这个id是惟一的。在接下来的请求中,会话id标识了这个用户,会话对象作为请求的一部分发送给servlet,servlet能从会话对象中读取信息,或者为其添加信息。 在用户闲置了一段时间后,这个会话对象就失效了,会话对象要被删除,这段时间默认是30分钟,当然可以在系统管理工具中设置这个时间。也可以通过手工操作使会话失效,调用session.invalidate( )方法能使会话对象立即失效,并删除该对象所包含的数据及会话对象本身。 为了使应用具有session功能,java servlet技术提供了管理session的api和集中实现session的机制。java.servlet.http.httpsession就封装了http会话的全部功能,其主要的功能如下。 访问session session表现为httpsession对象。调用request对象的getsession方法访问session。这个方法返回当前客户端请求(request)所关联的session,如果不存在,则为当前请求(request)创建一个session。由于getsession方法可能会改变响应(response)的头信息,所以需要在获得printwriter或servletoutputstream之前被调用。
使属性和session相关联 可以通过名称使对象值属性和一个session相关联。例如把购物车作为属性存储在session中,在其他servlet中可以通过session再获得购物车。
// 得到用户session和购物篮 httpsession session = request.getsession(); shoppingcart cart = (shoppingcart)session.getattribute("cart"); …… session管理 由于没有办法知道http客户端是否不再需要session,因此每个session都关联一个时间期限使它的资源可以被回收。通过session的setmaxinactiveinterval和getmaxinactiveinterval方法访问超时时间。 为了确保session的有效、不超时,开发人员应该在service方法中周期性地访问session。当客户端完成一个(组)完整的交互过程后,可以使用invalidate()方法使服务器端的session无效,并清除session数据。 // 得到用户session和购物篮 httpsession session = request.getsession(); // 付款完成,使session无效 session.invalidate(); …… 实例:会话跟踪servlet程序 下面就举一个关于会话跟踪的具体例子,见示例14-5。 【程序源代码】 1 // ==================== program description ========================== 2 // 程序名称:示例14-5 : sessionservlet.java 3 // 程序目的:编写会话跟踪的servlet程序 4 // ============================================================== 5 package examples.servlets; 6 7 import java.io.*; 8 import java.util.enumeration; 9 import javax.servlet.*; 10 import javax.servlet.http.*; 11 12 public class sessionservlet extends httpservlet 13 { 14 public void doget (httpservletrequest req, httpservletresponse res) 15 throws servletexception, ioexception 16 { 17 httpsession session = req.getsession(true); 18 res.setcontenttype("text/html"); 19 printwriter out = res.getwriter(); 20 out.println(" " + "sessionservlet output " + 21 ""); 22 out.println(" bea_button_final_web.gif align=right>"); 23 out.println("
sessionservlet output "); 24 integer ival = (integer) session.getattribute("sessiontest.counter"); 25 if (ival==null) 26 ival = new integer(1); 27 else 28 ival = new integer(ival.intvalue() + 1); 29 session.setattribute("sessiontest.counter", ival); 30 out.println("you have hit this page " + ival + " times."); 31 out.println("click 32 ">here"); 33 out.println(" to ensure that session tracking is working even " + 34 "if cookies aren’t supported. "); 35 out.println("note that by default url rewriting is not enabled " + 36 "because of its expensive overhead"); 37 out.println(" "); 38 out.println(" request and session data:"); 39 out.println("session id in request: " + 40 req.getrequestedsessionid()); 41 out.println(" session id in request from cookie: " + 42 req.isrequestedsessionidfromcookie()); 43 out.println(" session id in request from url: " + 44 req.isrequestedsessionidfromurl()); 45 out.println(" valid session id: " + 46 req.isrequestedsessionidvalid()); 47 out.println("session data:"); 48 out.println("new session: " + session.isnew()); 49 out.println(" session id: " + session.getid()); 50 out.println(" creation time: " + session.getcreationtime()); 51 out.println(" last accessed time: " + 52 session.getlastaccessedtime()); 53 54 out.println(""); 55 } 56 57 } 【程序输出结果】如图14-7所示。 
图14-7 返回session的信息 【程序注解】 这个程序实现了doget方法,而不是我们经常见到的service方法。第17行用getsession获取会话对象,true表示如果这个会话对象不存在就创建新的。第24行用getattribute( )方法通过session找到与interger相关联的变量。如果不存在这个integer变量,就创建一个整数变量,并用setattribute( )方法将这个整数变量与session相关联;如果存在这个变量,就将整数值加1,表示访问次数增加了。 在向客户端显示信息时,调用了很多session获得属性的方法。getrequestedsessionid() 方法将返回session的id,isrequestedsessionidfromcookie()判断这个request是不是从cookie发出的,isrequestedsessionidfromurl()判断这个request是不是从url发出的,isrequestedsessionidvalid( )方法返回当前请求的session是不是合法。isnew()方法返回这个session是不是新建的。getid()返回session的id,getcreationtime()返回session的创建时间,getlastaccessedtime()返回上次访问时间。
|