- JSP 基础教程
- JSP - 首页
- JSP - 概述
- JSP - 环境设置
- JSP - 架构
- JSP - 生命周期
- JSP - 语法
- JSP - 指令
- JSP - 动作
- JSP - 隐式对象
- JSP - 客户端请求
- JSP - 服务器响应
- JSP - HTTP 状态码
- JSP - 表单处理
- JSP - 编写过滤器
- JSP - Cookie 处理
- JSP - 会话跟踪
- JSP - 文件上传
- JSP - 处理日期
- JSP - 页面重定向
- JSP - 点击计数器
- JSP - 自动刷新
- JSP - 发送电子邮件
- 高级 JSP 教程
- JSP - 标准标签库
- JSP - 数据库访问
- JSP - XML 数据
- JSP - JavaBean
- JSP - 自定义标签
- JSP - 表达式语言
- JSP - 异常处理
- JSP - 调试
- JSP - 安全性
- JSP - 国际化
- JSP 有用资源
- JSP - 问题与解答
- JSP - 快速指南
- JSP - 有用资源
- JSP - 讨论
JSP - 会话跟踪
在本章中,我们将讨论 JSP 中的会话跟踪。HTTP 是一种“无状态”协议,这意味着每次客户端检索网页时,客户端都会打开与 Web 服务器的单独连接,并且服务器不会自动保留任何先前客户端请求的记录。
在 Web 客户端和服务器之间维护会话
现在让我们讨论一些在 Web 客户端和 Web 服务器之间维护会话的选项:
Cookie
Web 服务器可以为每个 Web 客户端分配一个唯一的会话 ID 作为 Cookie,并在客户端的后续请求中使用接收到的 Cookie 进行识别。
这可能不是一种有效的方法,因为浏览器有时不支持 Cookie。不建议使用此过程来维护会话。
隐藏表单字段
Web 服务器可以发送一个隐藏的 HTML 表单字段,并附带一个唯一的会话 ID,如下所示:
<input type = "hidden" name = "sessionid" value = "12345">
这意味着,当表单提交时,指定的名称和值会自动包含在 **GET** 或 **POST** 数据中。每次 Web 浏览器发送请求时,都可以使用 **session_id** 值来跟踪不同的 Web 浏览器。
这可能是跟踪会话的一种有效方法,但点击常规的 (<A HREF...>) 超文本链接不会导致表单提交,因此隐藏表单字段也不能支持常规的会话跟踪。
URL 重写
您可以在每个 URL 的末尾附加一些额外的数据。这些数据标识会话;服务器可以将该会话标识符与其存储的有关该会话的数据相关联。
例如,对于 **https://tutorialspoint.com/file.htm;sessionid=12345**,会话标识符附加为 **sessionid = 12345**,Web 服务器可以访问它来识别客户端。
URL 重写是维护会话的一种更好的方法,并且在浏览器不支持 Cookie 时也能正常工作。这里的缺点是您必须动态生成每个 URL 以分配会话 ID,即使页面是一个简单的静态 HTML 页面。
session 对象
除了上述选项外,JSP 还使用 servlet 提供的 HttpSession 接口。此接口提供了一种跨越以下范围识别用户的方法。
- 一个页面请求或
- 访问网站或
- 存储有关该用户的信息
默认情况下,JSP 启用了会话跟踪,并且会为每个新的客户端自动实例化一个新的 HttpSession 对象。禁用会话跟踪需要通过将页面指令的 session 属性显式设置为 false 来关闭它,如下所示:
<%@ page session = "false" %>
JSP 引擎通过隐式 **session** 对象向 JSP 作者公开 HttpSession 对象。由于 **session** 对象已提供给 JSP 程序员,因此程序员可以立即开始从对象存储和检索数据,而无需任何初始化或 **getSession()**。
以下是通过 session 对象可用的重要方法的摘要:
序号 | 方法和描述 |
---|---|
1 |
public Object getAttribute(String name) 此方法返回在此会话中与指定名称绑定的对象,如果在该名称下没有绑定任何对象,则返回 null。 |
2 |
public Enumeration getAttributeNames() 此方法返回一个 String 对象的 Enumeration,其中包含绑定到此会话的所有对象的名称。 |
3 | public long getCreationTime() 此方法返回创建此会话的时间,以 1970 年 1 月 1 日午夜以来的毫秒数(格林威治标准时间)衡量。 |
4 | public String getId() 此方法返回一个包含分配给此会话的唯一标识符的字符串。 |
5 | public long getLastAccessedTime() 此方法返回客户端上次发送与此会话关联的请求的时间,以 1970 年 1 月 1 日午夜以来的毫秒数(格林威治标准时间)衡量。 |
6 | public int getMaxInactiveInterval() 此方法返回 servlet 容器在客户端访问之间保持此会话打开的最大时间间隔(以秒为单位)。 |
7 | public void invalidate() 此方法使此会话无效,并取消绑定与此会话绑定的任何对象。 |
8 | public boolean isNew() 如果客户端尚不知道该会话或客户端选择不加入该会话,则此方法返回 true。 |
9 | public void removeAttribute(String name) 此方法从此会话中删除与指定名称绑定的对象。 |
10 | public void setAttribute(String name, Object value) 此方法使用指定的名称将对象绑定到此会话。 |
11 | public void setMaxInactiveInterval(int interval) 此方法指定 servlet 容器在客户端请求之间失效此会话之前的时间(以秒为单位)。 |
会话跟踪示例
此示例说明如何使用 HttpSession 对象查找会话的创建时间和上次访问时间。如果不存在,我们将与请求关联一个新会话。
<%@ page import = "java.io.*,java.util.*" %> <% // Get session creation time. Date createTime = new Date(session.getCreationTime()); // Get last access time of this Webpage. Date lastAccessTime = new Date(session.getLastAccessedTime()); String title = "Welcome Back to my website"; Integer visitCount = new Integer(0); String visitCountKey = new String("visitCount"); String userIDKey = new String("userID"); String userID = new String("ABCD"); // Check if this is new comer on your Webpage. if (session.isNew() ){ title = "Welcome to my website"; session.setAttribute(userIDKey, userID); session.setAttribute(visitCountKey, visitCount); } visitCount = (Integer)session.getAttribute(visitCountKey); visitCount = visitCount + 1; userID = (String)session.getAttribute(userIDKey); session.setAttribute(visitCountKey, visitCount); %> <html> <head> <title>Session Tracking</title> </head> <body> <center> <h1>Session Tracking</h1> </center> <table border = "1" align = "center"> <tr bgcolor = "#949494"> <th>Session info</th> <th>Value</th> </tr> <tr> <td>id</td> <td><% out.print( session.getId()); %></td> </tr> <tr> <td>Creation Time</td> <td><% out.print(createTime); %></td> </tr> <tr> <td>Time of Last Access</td> <td><% out.print(lastAccessTime); %></td> </tr> <tr> <td>User ID</td> <td><% out.print(userID); %></td> </tr> <tr> <td>Number of visits</td> <td><% out.print(visitCount); %></td> </tr> </table> </body> </html>
现在将上述代码放入 **main.jsp** 中,并尝试访问 **https://127.0.0.1:8080/main.jsp**。运行 URL 后,您将收到以下结果:
欢迎访问我的网站
会话信息
会话信息 | 值 |
---|---|
ID | 0AE3EC93FF44E3C525B4351B77ABB2D5 |
创建时间 | 2010 年 6 月 8 日星期二 17:26:40 格林威治标准时间 +04:00 |
上次访问时间 | 2010 年 6 月 8 日星期二 17:26:40 格林威治标准时间 +04:00 |
用户 ID | ABCD |
访问次数 | 0 |
现在尝试第二次运行相同的 JSP,您将收到以下结果。
欢迎再次访问我的网站
会话信息
信息类型 | 值 |
---|---|
ID | 0AE3EC93FF44E3C525B4351B77ABB2D5 |
创建时间 | 2010 年 6 月 8 日星期二 17:26:40 格林威治标准时间 +04:00 |
上次访问时间 | 2010 年 6 月 8 日星期二 17:26:40 格林威治标准时间 +04:00 |
用户 ID | ABCD |
访问次数 | 1 |
删除会话数据
完成用户会话数据后,您有几个选项:
**删除特定属性** - 您可以调用 **public void removeAttribute(String name)** 方法删除与特定键关联的值。
**删除整个会话** - 您可以调用 **public void invalidate()** 方法丢弃整个会话。
**设置会话超时** - 您可以调用 **public void setMaxInactiveInterval(int interval)** 方法单独设置会话的超时时间。
**注销用户** - 支持 servlet 2.4 的服务器,您可以调用 **logout** 将客户端注销 Web 服务器并使属于所有用户的会话无效。
**web.xml 配置** - 如果您使用的是 Tomcat,除了上述方法外,您还可以如下在 web.xml 文件中配置会话超时时间。
<session-config> <session-timeout>15</session-timeout> </session-config>
超时时间以分钟为单位表示,并覆盖 Tomcat 中的默认超时时间(30 分钟)。
servlet 中的 **getMaxInactiveInterval( )** 方法以秒为单位返回该会话的超时时间。因此,如果您的会话在 web.xml 中配置为 15 分钟,则 **getMaxInactiveInterval( )** 返回 900。