day22-web开发会话技术04
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:
<!--CreateSession2--> <servlet> <servlet-name>CreateSession2</servlet-name> <servlet-class>com.li.session.CreateSession2</servlet-class> </servlet> <servlet-mapping> <servlet-name>CreateSession2</servlet-name> <url-pattern>/createSession2</url-pattern> </servlet-mapping> <!--ReadSession2--> <servlet> <servlet-name>ReadSession2</servlet-name> <servlet-class>com.li.session.ReadSession2</servlet-class> </servlet> <servlet-mapping> <servlet-name>ReadSession2</servlet-name> <url-pattern>/readSession2</url-pattern> </servlet-mapping>
CreateSession2:
package com.li.session; import javax.servlet.*; import javax.servlet.http.*; import java.io.IOException; import java.io.PrintWriter; public class CreateSession2 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //System.out.println("CreateSession2 被调用"); //1.创建session HttpSession session = request.getSession(); System.out.println("CreateSession2 sid= " + session.getId()); //2.设置生命周期为60秒 session.setMaxInactiveInterval(60); //3.放属性 session.setAttribute("u", "jack"); //4.给浏览器发送一个回复 response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); writer.print("<h1>创建session成功,设置生命周期为60s</h1>"); writer.flush(); writer.close(); } }
ReadSession2:
package com.li.session; import javax.servlet.*; import javax.servlet.http.*; import java.io.IOException; import java.io.PrintWriter; public class ReadSession2 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } @Override 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已经被销毁了"); } //3.给浏览器发送一个回复 response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); writer.print("<h1>读取session成功</h1>"); writer.flush(); writer.close(); } }
-
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:
<!--DeleteSession--> <servlet> <servlet-name>DeleteSession</servlet-name> <servlet-class>com.li.session.DeleteSession</servlet-class> </servlet> <servlet-mapping> <servlet-name>DeleteSession</servlet-name> <url-pattern>/deleteSession</url-pattern> </servlet-mapping>
DeleteSession:
package com.li.session; import javax.servlet.*; import javax.servlet.http.*; import java.io.IOException; import java.io.PrintWriter; public class DeleteSession extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //System.out.println("DeleteSession 被调用"); //演示如何删除session HttpSession session = request.getSession(); session.invalidate(); //如果要删除session的某个方法,使用session.removeAttribute //给浏览器发送一个回复 response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); writer.print("<h1>删除session成功</h1>"); writer.flush(); writer.close(); } }
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:
package com.li.session.hw; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; @WebServlet(name = "LoginCheckServlet", urlPatterns = {"/loginCheckServlet"}) public class LoginCheckServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /** * 首先在loginCheckServlet判断用户数据是否合法。 * 1.如果合法,创建一个session,给session设置用户数据,并直接请求转发到ManageServlet * 2.如果非法,请求转发到error.html。 */ //获取表单数据 String username = request.getParameter("username"); String pwd = request.getParameter("pwd"); if ("666666".equals(pwd)) {//如果数据合法 //请求转发到ManageServlet HttpSession session = request.getSession(); session.setAttribute("username", username); //服务器来解析 / request.getRequestDispatcher("/manageServlet").forward(request, response); } else {//数据非法,请求转发到error.html //服务器来解析 / request.getRequestDispatcher("/error.html").forward(request, response); } } }
ManageServlet:
package com.li.session.hw; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; import java.io.PrintWriter; @WebServlet(name = "ManageServlet", urlPatterns = {"/manageServlet"}) public class ManageServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /** * 在ManageServlet中,首先获取session。 * 1.如果该session中有设置的用户数据,说明在此次请求之前,创建过session, * 并在服务器保存了该session对象,即用户登录过,因此可以直接访问管理页面。 * 2.否则,就说明此次请求之前没有创建过session,该session是新创建的, * 用户没有登录验证过,就重定向到login.html。 */ HttpSession session = request.getSession(); Object username = session.getAttribute("username"); // username=null 说明是新创建的session,说明该用户没有登录过 if (username == null) { //浏览器解析的 / response.sendRedirect("/cs/login.html"); return; } else { //否则说明浏览器有对应的session(即已经登录验证过),可以直接访问管理页面 //显示页面 response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); writer.print("<h1>用户管理页面</h1><br/>" + "欢迎你,管理员:" + username.toString()); writer.flush(); writer.close(); } } }
error.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录失败</title> </head> <body> <h1>登录失败</h1> <a href="/cs/login.html">点击返回重新登录</a> </body> </html>
login.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录页面</title> </head> <body> <form action="/cs/loginCheckServlet" method="post"> 用户名:<input type="text" name="username"/><br/><br/> 密码:<input type="password" name="pwd"/><br/> <input type="submit" value="登录"/> </form> </body> </html>
-
redeployTomcat,在浏览器访问
http://localhost:8080/cs/login.html
,输入正确的密码,成功登录并显示页面。 -
此时如果在新标签页地址栏访问
http://localhost:8080/cs/manageServlet
,是可以直接显示页面的,因为之前已经登录过了。 -
如果没有登录就访问
http://localhost:8080/cs/manageServlet
,会重定向到登录页面,无法直接访问管理页面。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!