4.5 session对象

session(会话)对象是类javax.servlet.Httpsession的一个对象。session是从客户端连接服务器开始,直到与服务器断开连接为止。session对象用于保存每个与服务器建立连接的客户端的信息,session的ID保存于客户端的Cookie中,这个sessionID标识唯一的用户,与其他用户的sessionID不同。接下来针对session的概念与其中数据的处理方式进行讨论。

4.5.1 session的概念

session存在于服务器端,当客户端用户向服务器提出请求打开网页时,若该网页中包含了为用户建立session的程序代码,则session便会产生。这个session可用来存放属于该用户的数据,且每一份网页都可以使用这个session中的内容,不过由于每一个session都是独立的,且其中数据内容互不相干,对不同的用户来说,网页所读取的数据也就不同。如图4-20所示为session数据存取的方式。

图4-20 session数据存取方式示意图

在服务器内部可能会由于有多个不同的用户同时上线而建立多个session,这样,当用户向服务器提出请求时,服务器端会用以下方法来辨别该用户属于哪一个session:当服务器为某一用户建立session之后,会给session一个用于识别的字符串,此字符串数据还会被传送到客户端并记录在浏览器的Cookie中,当用户再度向服务器提出请求时,此字符串数据便会一并传送,这样,服务器端在收到此字符串数据后,再与各session的标识符串进行对比后,便可知道用户拥有哪一份session数据。

4.5.2 session对象的ID

当一个客户首次访问服务器上的一个JSP页面时,JSP引擎产生一个session对象,同时分配一个String类型的ID号,JSP引擎同时将这个ID号发送到客户端,存放在Cookie(Cookie是Web服务器保存在用户硬盘上的一段文本)中,这样session对象和客户之间就建立了一一对应的关系。当客户再访问连接该服务器的其他页面时,不再分配给客户新的session对象,直到客户关闭浏览器后,服务器端该客户的session对象才取消,并且和客户的会话对应关系消失。当客户重新打开浏览器再连接到该服务器时,服务器为该客户再创建一个新的session对象。

采用getId()方法返回session对象在服务器端的编号。每生成一个session对象,服务器都会给它一个编号,并且该编号不会重复,这样服务器才能根据编号来识别session,并且正确地处理某一特定的session及其提供的服务。

4.5.3 session的有效期限

session和application相同,有其存在的期限,当以下4种情况发生其一时,session与其中的数据便会清空。

用户关闭当前正在使用的浏览器程序。

关闭网页服务器。

用户未向服务器提出请求超过预设的时间,Tomcat服务器预设为30分钟。

运行程序结束session。

简要介绍了session之后,接下来将进一步讨论使用session内置对象处理session中数据的方式。

4.5.4 访问session中的数据

session对象是由HttpSession接口衍生而来的,在该接口下提供了访问session数据的方法。

1. 建立session变量

在JSP中不需要特别设置程序代码来建立用户session,当程序使用了session对象时,便会自动建立session,而下面这行语句便是在session中新增变量数据的方式:

     session.setAttribute("变量名称",变量内容)

变量内容可为字符串或者其他对象类型,接着再来看看如何使用这个方法在session中设置变量数据:

     <%
     session.setAttribute("id","编号");                //设置字符串
     session.setAttribute("expire",new Date(86400*10)); //设置日期
     session.setAttribute("level",new Integer(3));  //设置整数
     %>

上面的代码在session中建立了3个变量数据:id、expire与level,用户在当前浏览器中打开各个网页都能访问这些变量数据,不过如果是打开了另一个浏览器窗口,或者用户是其他联机的用户,将无法取得其中的内容。

2. 返回session中的变量

在session中设置了变量数据后,在其他各个网页中便可使用getValue读取其中的内容,此方法所返回的数据类型为对象(Object)类型,语法如下:

     session.getAttribute("变量名称")

3. 返回所有session中的变量名称

getValueNames()方法可以取出session中所有变量的名称,其结果为一个枚举类的实例。语法如下:

     session.getAttributeNames()

4. 清除session中的变量

removeValue()方法可以清除session中的变量数据,语法如下:

     session. removeAttribute("变量名称")

5. 结束session

对于已经建立的session,可使用invalidate()方法将其结束,语法如下:

     session.invalidate()

本小节介绍了JSP存取session数据的方式,下面接着介绍一些session特性的设置与常用的方法。

4.5.5 其他session对象的常用方法

除了访问session中数据的基本方法外,在session对象下还有一些很常用的方法,例如取得session标识符串、设置或取得系统预设结束session的时间等,如表4-6所示。

表4-6 session对象的常用方法

4.5.6 session对象应用实例

【例4-12】存取session对象数据。sessionInfo.jsp用来输入用户的信息,sessionData.jsp读取输入信息并设置session内容变量,usingSession.jsp取得session变量。

sessionInfo.jsp的代码如下:

     <%@ page contentType="text/html; charset=gb2312" %>
     <html>
     <body>
     <form method=post action=sessionData.jsp>
     <table>
     <tr><td>输入用户名:</td>
     <td><input type=text name=name></td>
     </tr>
     <tr><td>输入性别:</td>
     <td><input type=text name=sex></td>
     </tr>
     <tr colspan=2><td><input type=submit value=提交></td></tr>
     </table>
     </body>
     </html>

sessionData.jsp的代码如下:

     <%@ page language="java" contentType="text/html; charset=gb2312"%>
     <%
     request.setCharacterEncoding("gb2312");
     %>
     <html>
     <head>
     <title>设置 session 数据</title>
     </head>
     <body>
     <%
        String name = request.getParameter("name");
        String sex = request.getParameter("sex");       session.setAttribute("name", name);
        session.setAttribute("sex", sex);
     %>
     <a href="usingSession.jsp"> 显示已设置的session 数据内容 </a>
     </body>
     </html>

sessionInfo.jsp程序代码中引用了session对象的setAttribute()方法,在session中存入2笔变量数据:name和sex接下来显示网页usingSession.jsp的超级链接,其中包含取得此session数据内容的程序代码。

usingSession.jsp的代码如下:

这个网页主要是取得前一个网页记录在session中的数据,然后在网页中显示出来,程序代码取得session中的变量值,依序显示了session中的变量名称及其内容。在这里不像以前那样在页面之间跳转时参数要经过传递才能正确显示,此例采用session保存用户的信息,非常方便。

当用户单击sessionData.jsp网页超级链接时,由于均属于同一个session,因此usingSession.jsp网页就取得了sessionData.jsp网页所设置的session数据内容,如图4-21所示。

图4-21 设置并获取session数据

现在重新打开一个新的浏览器窗口,然后直接输入usingSession.jsp网页的网址进行浏览,由于这是一个全新的session,而且没有经过第一个网页的设置,因此这个session并没有包含任何数据内容,如图4-22所示。

图4-22 直接查看usingSession.jsp的运行结果

注意

session.getValue()方法所返回的数据类型为对象(Object)类型,可以根据程序的需要转换为其他数据类型。

【例4-13】引用session对象方法,显示session对象中部分属性值。此例中包含了两个程序sessionMethod.jsp和sessionMethodInfo.jsp。使用表4-6中的方法来取得与session有关的信息。其中,isNew()方法会判断session是否为新建的,并返回布尔值true或false。新建session的意义是指程序调用session对象在服务器端建立session,而尚未将此session的信息记录到客户端的Cookie中。

sessionMethod.jsp的代码如下:

在浏览器中打开http://localhost:8080/ch04/session/sessionMethod.jsp,则返回session为新建的信息true,如图4-23所示。

图4-23 sessionMethod.jsp的运行结果

sessionMethodInfo.jsp的代码如下:

当通过超级链接链接到sessionMethodInfo.jsp时,isNew()方法返回false,表示这是一个已经存在的session。除此之外,代表session身份的标识符串也相同,表示这两个页面是同一个session,如图4-24所示。session1对象user1的取值为null,是由于在sessionMethod.jsp页面中采用了session.removeAttribute("user1");删除了与user1相关联的属性,而user2的值不变。

图4-24 sessionMethodInfo.jsp的运行结果

如果把session.removeAttribute("user1");换成session.invalidate();,则跳转到sessionMethodInfo.jsp页面时会产生一个新的session对象,如图4-25所示。和前面两个图比较,除了新建session为true之外,标识符串也不相同,session对象的value都为null,表示这是一个全新的session。

图4-25 结束session后sessionMethodInfo.jsp的运行结果

关闭浏览器,然后将其重新打开,查看sessionMethod.jsp,也会产生一个全新的session,如图4-26所示。

图4-26 重新打开浏览器获取新session数据

【例4-14】创建sessionCount.jsp页面,统计访问站点的用户数目。

sessionCount.jsp的代码如下:

程序运行结果如图4-27所示。由于采用if(session.isNew())来判断是否是一个新的用户,所以在每个页面刷新时计数器并不会增加,只有开启一个新的浏览器窗口才会计数。

图4-27 sessionCount.jsp统计访问站点的用户数

另外需要注意的是,如果在执行本程序时不是新开启一个浏览器,会出现如图4-28所示的界面,显示计数器为null。这是由于if(session.isNew())判断此时不是一个新的session对象,所以并没有将Num变量值存入session。通过<%=session.getAttribute("Num")%>读取session对象的值是null。

图4-28 session计数器为null