session 生命周期
Session 生命周期-说明
- public void setMaxInactiveInterval(int interval) 设置 Session 的超时时间(以秒为单位),超过指定的时长,Session 就会被销毁。
- 值为正数的时候,设定 Session 的超时时长。
- 负数表示永不超时
- public int getMaxInactiveInterval()获取 Session 的超时时间
- public void invalidate() 让当前 Session 会话立即无效
- 如果没有调用 setMaxInactiveInterval() 来指定 Session 的生命时长,Tomcat 会以 Session默认时长为准,Session 默认的超时为 30 分钟, 可以在 tomcat 的 web.xml 设置
- Session 的生命周期指的是 :客户端/浏览器两次请求最大间隔时长,而不是累积时长。即当客户端访问了自己的 session,session 的生命周期将从 0 开始重新计算。(解读: 指的是同一个会话两次请求之间的间隔时间)
- 底层: Tomcat 用一个线程来轮询会话状态,如果某个会话的空闲时间超过设定的最大值,则将该会话销毁
代码演示说明 Session 的生命周期
创建CreateSession2
public class CreateSession2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("CreateSession2 被调用"); //创建session HttpSession session = request.getSession(); System.out.println("CreateSession2 sid= " + session.getId()); //设置生命周期为 60s session.setMaxInactiveInterval(60); session.setAttribute("u", "jack"); //回复一下浏览器 response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); writer.println("<h1>创建session成功, 设置生命周期60s</h1>"); writer.flush(); writer.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
创建ReadSession2
public class ReadSession2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //System.out.println("ReadSession2 被调用..."); //1. 获取到session HttpSession session = request.getSession(); System.out.println("ReadSession2 sid= " + session.getId()); //2. 读取session的属性 Object u = session.getAttribute("u"); if (u != null) { System.out.println("读取到session属性 u= " + (String) u); } else { System.out.println("读取不到session属性 u 说明原来的session被销毁"); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
解读Session 的生命周期
- 指的是两次访问 session 的最大间隔时间
- 如果你在 session 没有过期的情况下,操作 session, 则会重新开始计算生命周期
- session 是否过期,是由服务器来维护和管理
- 如我们调用了 invaliate() 会直接将该 session 删除/销毁
- 如果希望删除 session 对象的某个属性, 使用 removeAttribu(“xx”)
代码示例
创建DeleteSession
public class DeleteSession extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("DeleteSession 被调用..."); //演示如何删除session HttpSession session = request.getSession(); session.invalidate(); // 如果你要删除session的某个属性 //session.removeAttribute("xxx"); //回复一下浏览器 response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); writer.println("<h1>删除session成功</h1>"); writer.flush(); writer.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
Session 经典案例-防止非法进入管理页面
需求
只要密码为 666666, 我们认为就是登录成功
用户名不限制
- 如果验证成功,则进入管理页面 ManageServelt.java ,否则进入 error.html
- 如果用户直接访问 ManageServet.java , 重定
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录页面</title> </head> <body> <h1>用户登录界面</h1> <form action="/cs/loginCheck" method="post"> u:<input type="text" name="username"><br/> p:<input type="password" name="pwd"><br/> <input type="submit" value="登录"> </form> </body> </html>
LoginCheckServlet
public class LoginCheckServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("LoginCheckServlet 被调用.."); //功能-> 自己拆解 -> 逐步实现 //1. 得到提交的用户名和密码 String username = request.getParameter("username"); String password = request.getParameter("password"); if("666666".equals(password)) {//认为合法 //把用户名保存到 session HttpSession session = request.getSession(); session.setAttribute("loginuser", username); //请求转发到ManageServlet request.getRequestDispatcher("/manage").forward(request, response); } else { //请求转发进入到 error.html request.getRequestDispatcher("/error.html").forward(request, response); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
ManageServlet
public class ManageServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //判断该用户是否登录过 HttpSession session = request.getSession(); Object loginuser = session.getAttribute("loginuser"); if(loginuser == null) {//说明该用户没有登录 //重新登录-> 请求重定向 //response.sendRedirect("/cs/userlogin.html"); response.sendRedirect(request.getContextPath() + "/userlogin.html"); return; } else { response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); writer.println("<h1>用户管理页面</h1>"); writer.println("欢迎你, 管理员:" + loginuser.toString()); writer.flush(); writer.close(); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
error.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录失败</title> </head> <body> <h1>登录失败</h1> <!-- web工程路径专题 1. a 标签是 浏览器解析 2. 第一 / 被解析成 http://localhost:8080/ 3. 如果没有 / 会以当前浏览器地址栏 的 http://localhost:8080/工程路径../资源 去掉资源部分作为参考路径 --> <a href="/cs/userlogin.html">点击重新登录</a> </body> </html>