day22-web开发会话技术04

打印 上一主题 下一主题

主题 598|帖子 598|积分 1794

WEB开发会话技术04

14.Session生命周期

14.1生命周期说明


  • public void setMaxInactiveInterval(int interval):设置session的超时时间(以秒为单位),超过指定的时长,session就会被销毁。
  • 值为正数的时候,设置session的超时时长。
  • 值为负数时,表示永不超时
  • public int getMaxInactiveInterval()表示获取session的超时时间
  • public void invalidate()表示让当前的session会话立即无效
  • 如果没有调用setMaxInactiveInterval(int interval)来指定session的生命时长,Tomcat会以session的默认时长为准,session的默认时长为30分钟,可以在tomcat目录的conf目录下的web.xml中设置。

  • Session的生命周期指的是:客户端两次请求的最大间隔时长,而不是累积时长。即当客户端访问了自己的session,session的生命周期将将从0开始重新计算。(指的是同一个会话两次请求之间的间隔时间)
    cookie的生命周期指的是累积时长

  • Tomcat用一个线程来轮询会话状态,如果某个会话的空闲时间超过设定的最大值,则将该会话销毁。
    说明:在存放session对象的map中,会记录所有session对象的生命周期和session的上次被访问时间。Tomcat维护的线程每隔一定时间就会去扫描这个map,如果发现有某个session对象的上次被访问时间已超过了其生命周期,就会将其删除。如果浏览器在对应session对象没有过期的情况下去访问该session,那么这个session的上次访问时间就会被更新成最新访问的时间。
14.2案例演示1

案例演示1:session的生命周期
web.xml:
  1. <servlet>
  2.     <servlet-name>CreateSession2</servlet-name>
  3.     <servlet-class>com.li.session.CreateSession2</servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6.     <servlet-name>CreateSession2</servlet-name>
  7.     <url-pattern>/createSession2</url-pattern>
  8. </servlet-mapping>
  9. <servlet>
  10.     <servlet-name>ReadSession2</servlet-name>
  11.     <servlet-class>com.li.session.ReadSession2</servlet-class>
  12. </servlet>
  13. <servlet-mapping>
  14.     <servlet-name>ReadSession2</servlet-name>
  15.     <url-pattern>/readSession2</url-pattern>
  16. </servlet-mapping>
复制代码
CreateSession2:
  1. package com.li.session;
  2. import javax.servlet.*;
  3. import javax.servlet.http.*;
  4. import java.io.IOException;
  5. import java.io.PrintWriter;
  6. public class CreateSession2 extends HttpServlet {
  7.     @Override
  8.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  9.         doPost(request, response);
  10.     }
  11.     @Override
  12.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13.         //System.out.println("CreateSession2 被调用");
  14.         //1.创建session
  15.         HttpSession session = request.getSession();
  16.         System.out.println("CreateSession2 sid= " + session.getId());
  17.         //2.设置生命周期为60秒
  18.         session.setMaxInactiveInterval(60);
  19.         //3.放属性
  20.         session.setAttribute("u", "jack");
  21.         //4.给浏览器发送一个回复
  22.         response.setContentType("text/html;charset=utf-8");
  23.         PrintWriter writer = response.getWriter();
  24.         writer.print("<h1>创建session成功,设置生命周期为60s</h1>");
  25.         writer.flush();
  26.         writer.close();
  27.     }
  28. }
复制代码
ReadSession2:
  1. package com.li.session;
  2. import javax.servlet.*;
  3. import javax.servlet.http.*;
  4. import java.io.IOException;
  5. import java.io.PrintWriter;
  6. public class ReadSession2 extends HttpServlet {
  7.     @Override
  8.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  9.         doPost(request, response);
  10.     }
  11.     @Override
  12.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13.         //System.out.println("ReadSession2 被调用");
  14.         //1.获取到session
  15.         HttpSession session = request.getSession();
  16.         System.out.println("ReadSession2 sid= " + session.getId());
  17.         //2.读取session的属性
  18.         Object u = session.getAttribute("u");
  19.         if (u != null) {
  20.             System.out.println("读取到session属性 u= " + (String) u);
  21.         } else {
  22.             System.out.println("读取不到session属性u,说明原来的session已经被销毁了");
  23.         }
  24.         //3.给浏览器发送一个回复
  25.         response.setContentType("text/html;charset=utf-8");
  26.         PrintWriter writer = response.getWriter();
  27.         writer.print("<h1>读取session成功</h1>");
  28.         writer.flush();
  29.         writer.close();
  30.     }
  31. }
复制代码

  • redeployTomcat,首先在浏览器中访问http://localhost:8080/cs/createSession2创建session,然后在设置的60s生命周期内访问http://localhost:8080/cs/readSession2读取session,后台输出如下:

  • 等待60s后,再次访问http://localhost:8080/cs/readSession2,后台输出如下:
    可以看到session的id和之前不一样了,说明服务器创建了新的session,原来的session因为超过了生命周期已经被销毁。
  • 在浏览器抓包,也可以看出服务器返回了一个新的jsessionid值:

  • 重新访问http://localhost:8080/cs/createSession2创建session,然后分别在其30s,70s后访问http://localhost:8080/cs/readSession2,后台输出的sid是一致的,说明session的生命周期的计算不是累积的,而是客户端两次请求的最大间隔时长。

14.2案例演示2

案例演示2:删除session
web.xml:
  1. <servlet>
  2.     <servlet-name>DeleteSession</servlet-name>
  3.     <servlet-class>com.li.session.DeleteSession</servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6.     <servlet-name>DeleteSession</servlet-name>
  7.     <url-pattern>/deleteSession</url-pattern>
  8. </servlet-mapping>
复制代码
DeleteSession:
  1. package com.li.session;
  2. import javax.servlet.*;
  3. import javax.servlet.http.*;
  4. import java.io.IOException;
  5. import java.io.PrintWriter;
  6. public class DeleteSession extends HttpServlet {
  7.     @Override
  8.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  9.         doPost(request, response);
  10.     }
  11.     @Override
  12.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13.         //System.out.println("DeleteSession 被调用");
  14.         //演示如何删除session
  15.         HttpSession session = request.getSession();
  16.         session.invalidate();
  17.         //如果要删除session的某个方法,使用session.removeAttribute
  18.         //给浏览器发送一个回复
  19.         response.setContentType("text/html;charset=utf-8");
  20.         PrintWriter writer = response.getWriter();
  21.         writer.print("<h1>删除session成功</h1>");
  22.         writer.flush();
  23.         writer.close();
  24.     }
  25. }
复制代码
redeployTomcat,首先访问http://localhost:8080/cs/createSession2,创建session,然后访问http://localhost:8080/cs/deleteSession,删除此session。这时我们再访问http://localhost:8080/cs/readSession2读取session当前的sid,可以发现session已经不再是之前那个session了,说明之前创建的session已经被删除。
后台输出如下:
15.Session经典案例-防止非法进入管理页面

需求说明:完成防止用户登录管理页面应用案例
说明:

  • 只要密码为666666,就认为是登录成功,用户名不限制
  • 如果验证成功,则进入管理页面ManageServlet.java,否则进入error.html
  • 如果用户直接访问ManageServlet.java,直接重定向到login.html。即不允许在未验证的情况下直接访问管理页面。
练习
思路:

  • 首先在loginCheckServlet判断用户数据是否合法。如果合法,创建保存一个session,将用户数据保存到session中,并请求转发到ManageServlet。如果非法,则请求转发到error.html。
  • 在ManageServlet中,首先获取session。如果该session中有设置的用户数据,说明在此次请求之前,创建过session,并在服务器保存了该session对象,即用户登录过,因此可以直接访问管理页面。否则,就说明此次请求之前没有创建过session,该session是新创建的,用户没有登录验证过,就重定向到login.html。
LoginCheckServlet:
  1. package com.li.session.hw;
  2. import javax.servlet.*;
  3. import javax.servlet.http.*;
  4. import javax.servlet.annotation.*;
  5. import java.io.IOException;
  6. @WebServlet(name = "LoginCheckServlet", urlPatterns = {"/loginCheckServlet"})
  7. public class LoginCheckServlet extends HttpServlet {
  8.     @Override
  9.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  10.         doPost(request, response);
  11.     }
  12.     @Override
  13.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  14.         /**
  15.          * 首先在loginCheckServlet判断用户数据是否合法。
  16.          * 1.如果合法,创建一个session,给session设置用户数据,并直接请求转发到ManageServlet
  17.          * 2.如果非法,请求转发到error.html。
  18.          */
  19.         //获取表单数据
  20.         String username = request.getParameter("username");
  21.         String pwd = request.getParameter("pwd");
  22.         if ("666666".equals(pwd)) {//如果数据合法
  23.             //请求转发到ManageServlet
  24.             HttpSession session = request.getSession();
  25.             session.setAttribute("username", username);
  26.             //服务器来解析 /
  27.             request.getRequestDispatcher("/manageServlet").forward(request, response);
  28.         } else {//数据非法,请求转发到error.html
  29.             //服务器来解析 /
  30.             request.getRequestDispatcher("/error.html").forward(request, response);
  31.         }
  32.     }
  33. }
复制代码
ManageServlet:
  1. package com.li.session.hw;
  2. import javax.servlet.*;
  3. import javax.servlet.http.*;
  4. import javax.servlet.annotation.*;
  5. import java.io.IOException;
  6. import java.io.PrintWriter;
  7. @WebServlet(name = "ManageServlet", urlPatterns = {"/manageServlet"})
  8. public class ManageServlet extends HttpServlet {
  9.     @Override
  10.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  11.         doPost(request, response);
  12.     }
  13.     @Override
  14.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  15.         /**
  16.          * 在ManageServlet中,首先获取session。
  17.          * 1.如果该session中有设置的用户数据,说明在此次请求之前,创建过session,
  18.          *   并在服务器保存了该session对象,即用户登录过,因此可以直接访问管理页面。
  19.          * 2.否则,就说明此次请求之前没有创建过session,该session是新创建的,
  20.          *   用户没有登录验证过,就重定向到login.html。
  21.          */
  22.         HttpSession session = request.getSession();
  23.         Object username = session.getAttribute("username");
  24.         // username=null 说明是新创建的session,说明该用户没有登录过
  25.         if (username == null) {
  26.             //浏览器解析的 /
  27.             response.sendRedirect("/cs/login.html");
  28.             return;
  29.         } else {
  30.             //否则说明浏览器有对应的session(即已经登录验证过),可以直接访问管理页面
  31.             //显示页面
  32.             response.setContentType("text/html;charset=utf-8");
  33.             PrintWriter writer = response.getWriter();
  34.             writer.print("<h1>用户管理页面</h1><br/>" + "欢迎你,管理员:"
  35.                     + username.toString());
  36.             writer.flush();
  37.             writer.close();
  38.         }
  39.     }
  40. }
复制代码
error.html:
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>登录失败</title>
  6. </head>
  7. <body>
  8. <h1>登录失败</h1>
  9. <a target="_blank" href="https://www.cnblogs.com/cs/login.html">点击返回重新登录</a>
  10. </body>
  11. </html>
复制代码
login.html:
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>登录页面</title>
  6. </head>
  7. <body>
  8. <form action="/cs/loginCheckServlet" method="post">
  9.     用户名:<input type="text" name="username"/><br/><br/>
  10.     密码:<input type="password" name="pwd"/><br/>
  11.     <input type="submit" value="登录"/>
  12. </form>
  13. </body>
  14. </html>
复制代码

  • redeployTomcat,在浏览器访问http://localhost:8080/cs/login.html,输入正确的密码,成功登录并显示页面。

  • 此时如果在新标签页地址栏访问http://localhost:8080/cs/manageServlet,是可以直接显示页面的,因为之前已经登录过了。

  • 如果没有登录就访问http://localhost:8080/cs/manageServlet,会重定向到登录页面,无法直接访问管理页面。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美丽的神话

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表