经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring Boot » 查看文章
day22-web开发会话技术04
来源:cnblogs  作者:一刀一个小西瓜  时间:2022/11/23 19:56:04  对本文有异议

WEB开发会话技术04

14.Session生命周期

14.1生命周期说明

  1. public void setMaxInactiveInterval(int interval):设置session的超时时间(以秒为单位),超过指定的时长,session就会被销毁。

  2. 值为正数的时候,设置session的超时时长。

  3. 值为负数时,表示永不超时

  4. public int getMaxInactiveInterval()表示获取session的超时时间

  5. public void invalidate()表示让当前的session会话立即无效

  6. 如果没有调用setMaxInactiveInterval(int interval)来指定session的生命时长,Tomcat会以session的默认时长为准,session的默认时长为30分钟,可以在tomcat目录的conf目录下的web.xml中设置。

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

    cookie的生命周期指的是累积时长

  8. Tomcat用一个线程来轮询会话状态,如果某个会话的空闲时间超过设定的最大值,则将该会话销毁。

    说明:在存放session对象的map中,会记录所有session对象的生命周期和session的上次被访问时间。Tomcat维护的线程每隔一定时间就会去扫描这个map,如果发现有某个session对象的上次被访问时间已超过了其生命周期,就会将其删除。如果浏览器在对应session对象没有过期的情况下去访问该session,那么这个session的上次访问时间就会被更新成最新访问的时间。

14.2案例演示1

案例演示1:session的生命周期

web.xml:

  1. <!--CreateSession2-->
  2. <servlet>
  3. <servlet-name>CreateSession2</servlet-name>
  4. <servlet-class>com.li.session.CreateSession2</servlet-class>
  5. </servlet>
  6. <servlet-mapping>
  7. <servlet-name>CreateSession2</servlet-name>
  8. <url-pattern>/createSession2</url-pattern>
  9. </servlet-mapping>
  10. <!--ReadSession2-->
  11. <servlet>
  12. <servlet-name>ReadSession2</servlet-name>
  13. <servlet-class>com.li.session.ReadSession2</servlet-class>
  14. </servlet>
  15. <servlet-mapping>
  16. <servlet-name>ReadSession2</servlet-name>
  17. <url-pattern>/readSession2</url-pattern>
  18. </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. }
  1. redeployTomcat,首先在浏览器中访问http://localhost:8080/cs/createSession2创建session,然后在设置的60s生命周期内访问http://localhost:8080/cs/readSession2读取session,后台输出如下:

    image-20221123160535756
  2. 等待60s后,再次访问http://localhost:8080/cs/readSession2,后台输出如下:

    image-20221123160627142

    可以看到session的id和之前不一样了,说明服务器创建了新的session,原来的session因为超过了生命周期已经被销毁。

  3. 在浏览器抓包,也可以看出服务器返回了一个新的jsessionid值:

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

    image-20221123161637722

14.2案例演示2

案例演示2:删除session

web.xml:

  1. <!--DeleteSession-->
  2. <servlet>
  3. <servlet-name>DeleteSession</servlet-name>
  4. <servlet-class>com.li.session.DeleteSession</servlet-class>
  5. </servlet>
  6. <servlet-mapping>
  7. <servlet-name>DeleteSession</servlet-name>
  8. <url-pattern>/deleteSession</url-pattern>
  9. </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已经被删除。

后台输出如下:

image-20221123164650579

15.Session经典案例-防止非法进入管理页面

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

image-20221123165722319

说明:

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

练习

思路:

  1. 首先在loginCheckServlet判断用户数据是否合法。如果合法,创建保存一个session,将用户数据保存到session中,并请求转发到ManageServlet。如果非法,则请求转发到error.html。

  2. 在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 href="/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>
  1. redeployTomcat,在浏览器访问http://localhost:8080/cs/login.html,输入正确的密码,成功登录并显示页面。

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

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

原文链接:https://www.cnblogs.com/liyuelian/p/16919600.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号