HttpSession
一、HttpSession概述
1.1 什么是HttpSession
javax.servlet.http.HttpSession
接口表示一个会话,我们可以把一个会话内需要共享的数据保存到HttSession对象中!
主要作用: 作为session域, 实现同一次会话内.数据的共享, 一次会话,包含n次请求
同一次会话: 从打开浏览器访问服务器开始, 到关闭浏览器, 表示一次会话
1.2 HttpSession的使用
(1)获取HttpSession对象
HttpSession request.getSesssion()
:如果当前会话已经有了session对象那么直接返回,如果当前会话还不存在会话,那么创建session并返回;HttpSession request.getSession(boolean)
:当参数为true时,与requeset.getSession()相同。如果参数为false,那么如果当前会话中存在session则返回,不存在返回null;
(2) void invalidate() 让session失效, 这个session无效, session中存储的数据都失效
(3) void setMaxInactiveInterval(int interval) 设置session最大存活时间, 单位:秒
默认的存放时间: 30分钟, 从上一次请求到下一次请求之间超过30分钟, session删除
特征: 创建于服务器, 保存于服务器
Tomcat维护一个session池
1.3 HttpSession是域对象
我们已经学习过HttpServletRequest、ServletContext,它们都是域对象,现在我们又学习了一个HttpSession,它也是域对象。它们三个是Servlet中可以使用的域对象,而JSP中可以使用一个Page域对象
- HttpServletRequest:一个请求创建一个request对象,所以在同一个请求中可以共享request,例如一个请求从AServlet转发到BServlet,那么AServlet和BServlet可以共享request域中的数据;
- ServletContext:一个应用只创建一个ServletContext对象,所以在ServletContext中的数据可以在整个应用中共享,只要不启动服务器,那么ServletContext中的数据就可以共享;
- HttpSession:一个会话创建一个HttpSession对象,同一会话中的多个请求中可以共享session中的数据;
下面是session的域方法:
- void setAttribute(String name, Object value):用来存储一个对象,也可以称之为存储一个域属性,例如:session.setAttribute(“xxx”, “XXX”),在session中保存了一个域属性,域属性名称为xxx,域属性的值为XXX。请注意,如果多次调用该方法,并且使用相同的name,那么会覆盖上一次的值,这一特性与Map相同;
- Object getAttribute(String name):用来获取session中的数据,当前在获取之前需要先去存储才行,例如:String value = (String) session.getAttribute(“xxx”);,获取名为xxx的域属性;
- void removeAttribute(String name):用来移除HttpSession中的域属性,如果参数name指定的域属性不存在,那么本方法什么都不做;
- Enumeration getAttributeNames():获取所有域属性的名称;
二、HttpSession实现原理
服务器会为用户创建一个Session对象,并且把sessionId 以cookie的形式,保存在客户端浏览器上, 用户之后每次请求, 自动把cookie(JSESSIONID) 带回到服务器, 服务器根据sessionId匹配session池的对应的session的对象, 服务器知道当前请求是哪个会话的, 如果客户端的cookie被删除, 请求不会带JSessionId, 服务器,不知道哪个Session是这个用户的, 之前的为该用户创建的session失效了,谁也无法访问,就是个垃圾,服务器,等30分钟,删除这个session,
如果服务器把session删除, 就算客户端有jsession的Cookie, 也无法得到Session, 服务器会为你重新创建Session,并新的sessionId以Cookie的形式保存客户端
三、HttpSession与浏览器
session保存在服务器,而sessionId通过Cookie发送给客户端,但这个Cookie的生命不-1(cookie.setMaxAge(-1):cookie的maxAge属性的默认值就是-1),即只在浏览器内存中存在,也就是说如果用户关闭了浏览器,那么这个Cookie就丢失了。
当用户再次打开浏览器访问服务器时,就不会有sessionId发送给服务器,那么服务器会认为你没有session,所以服务器会创建一个session,并在响应中把sessionId通过Cookie发送给客户端。
你可能会说,那原来的session对象会怎样?当一个session长时间没人使用的话,服务器会把session删除了!这个时长在Tomcat中配置是30分钟,可以在${CATALANA}/conf/web.xml找到这个配置,当然你也可以在自己的web.xml中覆盖这个配置!
web.xml
<session-config>
<session-timeout>30</session-timeout>
</session-config>
session失效时间也说明一个问题!如果你打开网站的一个页面开始长时间不动,超出了30分钟后,再去点击链接或提交表单时你会发现,你的session已经丢失了!
四、HttpSession其他常用API
- String getId():获取sessionId;
- int getMaxInactiveInterval():获取session可以的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;
- void setMaxInactiveInterval(int interval):设置session允许的最大不活动时间(秒),如果设置为1秒,那么只要session在1秒内不被使用,那么session就会被移除;
- long getCreationTime():返回session的创建时间,返回值为当前时间的毫秒值;
- long getLastAccessedTime():返回session的最后活动时间,返回值为当前时间的毫秒值;
- void invalidate():让session失效!调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId;
- boolean isNew():查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。
4.1 退出例子
- 发送一个请求到LogoutServlet
- 让session失效
- 重定向到login.jsp
LogoutServlet:
@WebServlet("/LogoutServlet")
public class LogoutServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.让session失效
request.getSession().invalidate();
//2.重定向到login.jsp
response.sendRedirect(request.getContextPath()+"/login.jsp");
}
}
index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>首页</title>
</head>
<body>
<a href="<%=request.getContextPath()%>/LogoutServlet">退出</a>
</body>
</html>
4.2 验证码例子
- 用户填写验证, 点击登录,发送登录请求
- 先判断验证码是否一致(存在session的验证码与用户输入的验证码)
- 如果不一致, 直接响应"验证码错误",转发到login.jsp
- 如果一致, 做登录操作
login.jsp:
<%@ page import="com.fs.wwl.util.CookieUtil" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content