在本 Java Web 教程中,您将通过有用的代码示例了解 Java Web 应用程序开发中的会话管理。让我们开始定义会话。
表中的内容:
1. 什么是会话?
2. Java 中的会话管理
3. 获取或创建会话
4. 将数据绑定到会话
5. 配置会话超时
6. 使会话无效
1. 什么是会话?
就万维网而言,会话表示单个用户访问网站的时间段。当用户请求第一页时,会话开始。在会话期间,用户可以查看任意数量的页面。如果用户在给定的时间内(超时)没有请求任何页面,则会话结束。会话超时因服务器配置而异——通常为 15 到 30 分钟。
由于 HTTP 协议是无状态的,服务器可以通过 cookie、URL 重写或隐藏表单字段跟踪会话——以跨不同请求识别单个用户。使用 cookie 的会话跟踪是主要机制。如果用户的 Web 浏览器不支持 cookie,则可以使用 URL 重写或隐藏表单字段。
在 Web 开发中,程序员使用会话机制来管理仅在特定会话中持续存在的用户信息,例如身份验证状态、用户名或需要跨请求共享的任何数据。
2. Java 中的会话管理
在 Java 中,HttpSession 对象代表特定用户的会话。请注意,HttpSession是定义在javax.servlet包中的接口,而实际实现是由 servlet 容器(即像 Tomcat 这样的服务器)注入到HttpServletRequest中的。
您可以将用户相关信息以键值对的形式存储在会话中。HttpSession接口定义了setAttribute (key, value)方法来存储键值条目和getAttribute(key)方法来获取指定键的值。
默认情况下,Java 使用 cookie 进行会话跟踪。名为JSESSIONID 的 cookie临时存储在 Web 浏览器中。它用于跨不同请求识别同一用户。
3. 获取或创建会话
默认情况下,当用户访问网站时会自动创建一个会话。要获取代表用户会话的HttpSession对象,请在 Java Servlet的doGet()或doPost()方法中调用HttpServletRequest接口的getSession()方法。例如:
1
2
3
4
5
6
|
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
// work with the session...
}
|
请注意HttpServletRequest。getSession()方法返回与请求关联的当前会话,如果请求没有会话,则创建一个新会话。这意味着返回的HttpSession对象始终不为空。
要获取会话而不创建新会话(如果不存在),您可以在HttpServletRequest上使用调用getSession(false):
1
2
3
4
5
6
7
|
HttpSession session = request.getSession( false );
if (session != null ) {
// a session exists
} else {
// no session
}
|
在这种情况下,如果不存在会话,则返回值可以为 null - 因此需要 if-else 检查可空性。这也意味着getSession()等同于getSession(true)。
供您参考,以下 Java Servlet 打印当前会话的会话 ID、创建时间和上次访问时间:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package net.codejava;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
@WebServlet ( "/test_session" )
public class TestSessionServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public TestSessionServlet() {
super ();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
PrintWriter writer = response.getWriter();
writer.println( "Session ID: " + session.getId());
writer.println( "Creation Time: " + new Date(session.getCreationTime()));
writer. println( "Last Accessed Time: " + new Date(session.getLastAccessedTime()));
}
}
|
您可以运行此 servlet 进行测试。结果将如下所示:
4. 将数据绑定到会话
在会话中存储值:
要在会话中存储值,请使用HttpSession对象的setAttribute(key, value)方法。例如,以下语句存储用户的用户名:
1
|
session.setAttribute( "username" , "Daniel Tran" );
|
这里,键是用户名,值是Daniel Tran。会话中存储的数据由服务器管理,会话结束时将被删除。
您可以在会话中存储任何类型的对象。例如,以下代码在会话中存储一个学生对象列表:
1
2
|
List<Student> students = studentDao.getStudents();
session.setAttribute( "listStudent" , students);
|
笔记:
每个用户都与不同的HttpSession对象相关联,因此为用户 #1 存储的值与为用户 #2 存储的值不同 - 尽管密钥相同。
如果键已经与一个值相关联,那么旧值将被新值替换。因此,您可以使用setAttribute()方法来更新会话中的值。
从 Java Servlet 中的会话中读取值:
要从会话中获取值,请使用HttpSession对象的getAttribute(key)方法。例如,以下代码从会话中获取用户名属性的值:
1
|
String username = (String) session.getAttribute( "username" );
|
我们需要转换为String类型,因为getAttribute()方法总是返回Object类型的值。
以下语句从会话中读取List集合:
1
|
List<Student> listStudents = (List<Student>) session.getAttribute( "listStudent" );
|
请注意,如果在会话中找不到给定的键, getAttribute(key)方法将返回空值。
从 JSP 中的会话中读取值:
在 JSP 中,要读取和显示存储在会话中的属性值,只需使用 EL(表达式语言),如下所示:
1
2
3
4
5
6
|
<%@ page language="java" %>
< html >
< body >
< p >Username: ${username}</ p >
</ body >
</ html >
|
在这里,JSP 处理器将在可能的范围(包括会话)中找到属性用户名。 或者您可以在表达式中明确指定会话范围:
1
|
< p >Username: ${sessionScope['username']}</ p >
|
从会话中删除值:
要从会话中删除与键关联的值,请使用removeAttribute(key)方法。例如:
1
|
session.removeAttribute( "username" );
|
此语句删除与属性用户名关联的值。
5.配置会话超时
如果用户在给定的时间内空闲(没有发出任何请求),他的会话就会过期——这意味着绑定到他的会话的所有数据都将从服务器中删除——会话被销毁。每个服务器都有不同的全局会话超时默认值,例如 Apache Tomcat 中的 30 分钟。
您可以通过修改其 Web 部署描述符文件 ( web.xml )为单个 Web 应用程序设置会话超时。例如:
1
2
3
4
5
6
7
8
|
<? xml version = "1.0" encoding = "UTF-8" ?>
< web-app... >
< session-config >
< session-timeout >15</ session-timeout >
</ session-config >
</ web-app >
|
这会覆盖服务器设置的全局会话超时,并将会话超时设置为 15 分钟。
您可以像这样以编程方式为单个会话设置超时值:
1
|
session.setMaxInactiveInterval( 300 );
|
这会将当前会话的超时设置为 300 秒。
阅读这篇文章,了解有关在 Java 中设置会话超时的更多详细信息。
6. 无效一个会话
默认情况下,只有在用户空闲一段时间后才会销毁会话。如果您想立即销毁单个会话,请像这样调用invalidate()方法:
1
|
session.invalidate();
|
这将删除绑定到会话的任何对象并将其销毁。
API参考: