一.Session简介
-
Session的使用场景
-
当我们登陆电商网站时,无论浏览哪个页面都会显示登陆人的名字,还可以随时查看购物车里面的商品
-
也就是说当一个用户浏览一个网站的不同页面时,服务器怎么知道此时是张三在访问还是李四在访问
这也就引出我们的另一个会话技术Session 与cookie不同session是保存在服务器端上,在每一次与浏览器的会话中,服务器都会创建该会话独享的session空间用于存储数据,用户浏览多个页面时可以从session对象中读取数据进行相关操作
-
会话
在解释session前,我们要先了解什么是会话。会话就是用户通过浏览器访问多个网站页面,并关闭浏览器这一过程,严谨的讲一次会话和浏览器保存的JSessionID和服务器端保存的Session对象有关
总之,用户通过浏览器访问服务器,并操作Session时,服务器会在内存中为这次会话分配一个Session对象,被该浏览器所独占。
这个session可以看作一个容器/集合,默认存在时间为30分钟(可以在web.xml文件中修改)
二.Session的简单理解
1. Session的存储结构
session的存储结构类似于HashMap,相当于一张表
2. Session简单的执行流程
总结session的实现基于cookie,服务器端通过得到cookie来判断是一个新的会话,还是以前的会话
三.Session的使用
-
创建session
getSession方法的调用在某些情况下就相当于创建了一个Session对象
HttpSession session = request.getSession();
什么时候创建session
- 浏览器的HTTP请求cookie中没有携带JSESSIONID
-
浏览器的HTTP请求cookie中携带了JSESSIONID,但在服务器内存中没有与其匹配的JESSIONID
抓包分析
如果浏览器没有携带JESSIONID,操作session时服务器会为该浏览器分配一个ID以cookie的形式返回给浏览器进行保存
再此访问该服务器资源时浏览器会携带上次分配的JSESSIONID,到服务器端找到对应的session对象进行数据的操作
-
向session添加/读取属性
session.setAttribute("user", "jbc");
session.getAttribute("user");
-
移除session中的属性
session.removeAttribute("user");
-
获取JESSIONID
每一个session对象都有与之唯一对应的JSESSIONID
session.getID();
-
判断是否是新创建的session
session.isNew();
四.Session的生命周期
-
setMaxInterval方法设置session的生命周期(以秒为单位)
正数是session的超时时间
负数为永不超时
-
getMaxInterval()得到该session的生命周期
-
invalidate()销毁该session
-
在没有设置session的超时时长时默认为30分钟失效
-
Tomcat会在底层轮询存储JSESSIONID-session的容器,如果最近访问时间
lastAccessDate与现在的时间超过session的MaxInterval,就会销毁该session
要说明的是session的生命周期是:
浏览器能够访问到该session间隔的最大时长
,而不是累计时长,
在每次访问session时都会重置session的MaxInterval
代码举例
创建与访问该资源的浏览器关联的session对象,设置超时时长60秒
HttpSession session = request.getSession();
System.out.println("JSessionID= " + session.getId());
session.setMaxInactiveInterval(60);
session.setAttribute("user", "jbc");
读取当前会话的session中的数据
HttpSession session = request.getSession();
System.out.println("JSessionID= " + session.getId());
System.out.println(session.getAttribute("user"));
抓包分析
由于我们没有携带JSESSIONID,服务器分配了这次会话的ID
分析可知,在超过60秒后,服务器会将这次会话的session销毁,
这时我们再想要读取该session中的数据时,我们发现服务器端又返回了一个新的JSESSIONID,说明原来的会话已经被销毁,再对session进行操作时,服务器认为当前是新的会话,会创建session对象并返回给浏览器SID
需要再次说明的是session的生命周期是指,间隔的最大时长,如果在间隔时间内再次访问就会重置他的生命周期
五.应用实例
1.只要密码为 666666, 我们认为就是登录成功 ,用户名不限制
2. 如果验证成功,则进入管理页面 ManageServelt.java ,否则进入 error.html
3. 如果用户直接访问 ManageServet.java , 重定向到到 login.html
此案例只是为了理解session做的简单案例
package homework;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "LoginCheck", value = "/LoginCheck")
public class LoginCheck extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String pwd = request.getParameter("pwd");
//如果密码正确就创建一个会话
if ("666666".equals(pwd)) {
HttpSession session = request.getSession();
session.setAttribute("username", request.getParameter("username"));
request.getRequestDispatcher("/Manger").forward(request, response);
} else {
//否则请求转发到error.html
request.getRequestDispatcher("/error.html").forward(request, response);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
package homework;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "Manger", value = "/Manger")
public class Manager extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String username = (String) session.getAttribute("username");
//获得一个session对象如果该session对象是刚刚创建的
//该对象就不会存储username这一属性,就可以判断用户是非法访问的该资源
if (username == null) {
//重定向到login.html
response.sendRedirect("/session/login.html");
} else {
//如果是通过CheckLogin通过的就显示成功登陆
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("<h1>欢迎" + username + "登陆</h1>");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}