文章目录
Session有什么用
思考两个问题—抛砖引玉
- 不同的用户登录网站后,不管该用户浏览该网站的哪个页面,都可显示登录人的名字, 还可以随时去查看自己的购物车中的商品, 是如何实现的?
- 也就是说,一个用户在浏览网站不同页面时,服务器是如何知道是张三在浏览这个页面, 还是李四在浏览这个页面?
解决之道—session 技术
-
Session 是服务器端技术,服务器在运行时为每一个用户的浏览器创建一个其独享的 session 对象/集合。
-
由于 session 为各个用户浏览器独享,所以用户在访问服务器的不同页面时,可以从各自的 session 中读取/添加数据, 从而完成相应任务。
Session基本原理
Sesson 原理示意图
- 当用户打开浏览器,访问某个网站, 操作 session 时,服务器就会在内存(在服务端)为该 浏览器分配一个 session 对象,该 session 对象被这个浏览器独占, 如图
- 这个 session 对象也可看做是一个容器/集合,session 对象默认存在时间为 30min(这是在
tomcat/conf/web.xml
),也可修改
Session可以做什么
- 网上商城中的购物车
- 保存登录用户的信息
- 将数据放入到 Session 中,供用户在访问不同页面时,实现跨页面访问数据
- 防止用户非法登录到某个页面
- …
如何理解Session
- session 存储结构示意图
- 你可以把 session 看作是一容器类似 HashMap,有两列(K-V),每一行就是 session 的一个属性。
- 每个属性包含有两个部分,一个是该属性的名字(String),另外一个是它的值(Object)
Session常用方法
Session文档
HttpSession (Java™ EE 7 Specification APIs) (oracle.com)
getAttribute(String name)
- 获取指定名称的属性值setAttribute(String name, Object value)
- 设置指定名称的属性值removeAttribute(String name)
- 移除指定名称的属性值getId()
- 获取会话IDgetCreationTime()
- 获取会话创建时间getLastAccessedTime()
- 获取会话最后访问时间setMaxInactiveInterval(int interval)
- 设置会话的最大不活动时间间隔getMaxInactiveInterval()
- 获取会话的最大不活动时间间隔invalidate()
- 使会话无效isNew()
- 判断会话是否为新创建的
Session基本使用
-
创建和获取session, API一样
HttpSession hs = request.getSession()
第 1 次调用是创建 Session 会话, 之后调用是获取创建好的 Session 对象 -
向session添加属性
hs.setAttribute(String name,Object val);
-
从session获取某个属性
Object obj=hs.getAttribute(String name);
-
从 session 删除调某个属性
hs.removeAttribute(String name);
-
判断是不是刚创建出来的 Session
hs.isNew();
-
获取session的会话ID值
hs.getId();
session 底层实现机制
原理分析图(一图胜千言)
针对每个会话都有一个Session。
getSession()
方法是session创建的核心,极其重要!
它先判断浏览器是否带有jsessionid
这个cookie数据:
- 如果没有携带:就直接创建session,并且分配一个
jsessionid
,jsessionid
和session的管理通过一个Map结构维护; - 如果携带了:
- 如果不存在
id=jsessionid
的对象:就创建session,同时分配id; - 如果存在
id=jsessionid
的对象:就直接进行操作。
- 如果不存在
如果服务器在本次会话中创建了session,就返回Set-Cookie:jsessionid=xxx
。
演示创建session
-
需求: 演示 Session 底层实现机制-创建和读取 Session
-
创建
CreateSession.java
package com.hspedu.session; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; import java.io.PrintWriter; /** * @ClassName CreateSession * @Description 演示Session的创建 * @Author zephyr * @Date 2023/3/11 14:16 * @Version 1.0 */ @WebServlet(name = "CreateSession", value = "/createSession") public class CreateSession extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("================CreateSession 被调用================"); //1. 获取session,同时也可能创建session HttpSession session = request.getSession(); //2. 获取sessionId System.out.println("当前sessionId = " + session.getId()); //3. 给session存放数据 session.setAttribute("email", "zs@qq.com"); //4. 给浏览器发送回复 response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); writer.println("<h1>创建Session成功</h1>"); writer.flush(); writer.close(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
发送请求的时候没有携带JsessionId
,服务器收到之后为之创建一个JsessionId
并且在响应头里返回这个Set-Cookie: JESESSION=xxxxxxx
然后该JsessionId
就被存储在了浏览器的Cookie中
现在如果我们再次向客户端发起请求,携带了刚刚的JsessionId
,那么客户端就不会再为我们创建的新的session,而是使用与JsessionId
对应的session。并且,返回响应时也不会Set-Cookie: JESESSION=xxxxxxx
。
演示读取session
package com.hspedu.session;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @ClassName ReadSession
* @Description 演示读取session
* @Author zephyr
* @Date 2023/3/11 15:10
* @Version 1.0
*/
@WebServlet(name = "ReadSession", value = "/readSession")
public class ReadSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("================ReadSession 被调用================");
//1. 获取Session,如果没有session也会创建
HttpSession session = request.getSession();
//输出sessionId
System.out.println("sessionId = " + session.getId());
//2. 读取属性
Object email = session.getAttribute("email");
if (email != null){
System.out.println("session属性 email = " + (String) email);
} else {
System.out.println("session没有email属性");
}
//给浏览器回回复
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("<h1>创建/操作session成功</h1>");
writer.flush();
writer.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
Session实现原理动画
服务器是如何实现一个 session 为一个用户浏览器服务的
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 生命周期-应用实例
- 需求:代码演示说明Session的生命周期
createSession2.java
package com.hspedu.session;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @ClassName CreateSession2
* @Description TODO
* @Author zephyr
* @Date 2023/3/11 15:35
* @Version 1.0
*/
@WebServlet(name = "CreateSession2", value = "/createSession2")
public class CreateSession2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("================CreateSession2 被调用================");
//获取Session,如果没有session也会创建
HttpSession session = request.getSession();
//输出session的id
System.out.println("sessionId = " + session.getId());
//设置生命周期为60s
session.setMaxInactiveInterval(60);
//设置两个属性
session.setAttribute("u", "zephyr666");
//给浏览器发送回复
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("<h1>创建session成功,生命周期60s</h1>");
writer.flush();
writer.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
ReadSession2.java
package com.hspedu.session;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Time;
/**
* @ClassName ReadSession2
* @Description TODO
* @Author zephyr
* @Date 2023/3/11 15:37
* @Version 1.0
*/
@WebServlet(name = "ReadSession2", value = "/readSession2")
public class ReadSession2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("================ReadSession2 被调用================");
//获取Session
HttpSession session = request.getSession();
//输出session的id
System.out.println("sessionId = " + session.getId());
//获取session的属性
Object u = session.getAttribute("u");
if (u != null){
System.out.println("u = " + u);
} else {
System.out.println("读取不到session属性u");
}
//给浏览器回回复
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("<h1>读取session成功</h1>");
writer.flush();
writer.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
解读:Session 的生命周期
- 指的是两次访问 session 的最大间隔时间
- 如果你在 session 没有过期的情况下,操作 session, 则会重新开始计算生命周期
- session 是否过期,是由服务器来维护和管理
- 如我们调用了
invaliate()
会直接将该 session 删除/销毁- 如果希望删除 session 对象的某个属性, 使用
removeAttribute("xx")
DeleteSession.java
package com.hspedu.session;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
/**
* @ClassName DeleteSession
* @Description TODO
* @Author zephyr
* @Date 2023/3/11 17:26
* @Version 1.0
*/
@WebServlet(name = "DeleteSession", value = "/DeleteSession")
public class DeleteSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
// 让 Session 会话立即超时
session.invalidate();
response.setContentType("text/html;charset=utf-8"); // 先获取 Session 对象
response.getWriter().write("Session 已经设置为超时");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
Session 经典案例-防止非法进入管理页面
作业布置
-
需求说明: 完成防止用户登录管理页面应用案例(如图)
-
说明:
- 只要密码为
666666
, 我们认为就是登录成功 - 用户名不限制
- 如果验证成功,则进入管理页面
ManageServelt.java
,否则进入error.html
- 如果用户直接访问
ManageServet.java
, 重定向到到userlogin.html
- 只要密码为
作用讲评
-
创建
userlogin.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户登录</title></head> <body> <h1>用户登录</h1> <form action="/cs/loginCheck" method="post"> 用户名:<input type="text" name="username"/><br/><br/> 密 码:<input type="password" name="password"><br><br/> <input type="submit" value="登录"></form> </body> </html>
-
创建
LoginCheckServlet.java
package com.hspedu.session.homework; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; /** * @ClassName LoginCheckServlet * @Description 检测用户名和密码是否正确,正确则跳转到manage页面,错误则返回error.html * @Author zephyr * @Date 2023/3/13 11:12 * @Version 1.0 */ @WebServlet(name = "LoginCheckServlet", value = "/loginCheck") public class LoginCheckServlet extends HttpServlet { @Override protected void doGet(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); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
ManageServlet.java
package com.hspedu.session.homework; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; import java.io.PrintWriter; /** * @ClassName ManageServlet * @Description 管理员页面。通过session,如果已经登录过就可以直接访问,如果没有登陆过则重定向到登录页面。 * @Author zephyr * @Date 2023/3/13 11:15 * @Version 1.0 */ @WebServlet(name = "ManageServlet", value = "/manage") public class ManageServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("================ManageServlet 被调用================"); //判断该用户是否登陆过 HttpSession session = request.getSession(); Object loginuser = session.getAttribute("loginuser"); if (loginuser == null){ //重新登陆 response.sendRedirect(request.getContextPath() + "/userlogin.html"); } else { response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); writer.println("<h1>用户管理页面</h1>"); writer.println("欢迎你,管理员: " + loginuser.toString()); writer.flush(); writer.close(); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
文章目录
Session有什么用
思考两个问题—抛砖引玉
- 不同的用户登录网站后,不管该用户浏览该网站的哪个页面,都可显示登录人的名字, 还可以随时去查看自己的购物车中的商品, 是如何实现的?
- 也就是说,一个用户在浏览网站不同页面时,服务器是如何知道是张三在浏览这个页面, 还是李四在浏览这个页面?
解决之道—session 技术
-
Session 是服务器端技术,服务器在运行时为每一个用户的浏览器创建一个其独享的 session 对象/集合。
-
由于 session 为各个用户浏览器独享,所以用户在访问服务器的不同页面时,可以从各自的 session 中读取/添加数据, 从而完成相应任务。
Session基本原理
Sesson 原理示意图
- 当用户打开浏览器,访问某个网站, 操作 session 时,服务器就会在内存(在服务端)为该 浏览器分配一个 session 对象,该 session 对象被这个浏览器独占, 如图
- 这个 session 对象也可看做是一个容器/集合,session 对象默认存在时间为 30min(这是在
tomcat/conf/web.xml
),也可修改
Session可以做什么
- 网上商城中的购物车
- 保存登录用户的信息
- 将数据放入到 Session 中,供用户在访问不同页面时,实现跨页面访问数据
- 防止用户非法登录到某个页面
- …
如何理解Session
- session 存储结构示意图
- 你可以把 session 看作是一容器类似 HashMap,有两列(K-V),每一行就是 session 的一个属性。
- 每个属性包含有两个部分,一个是该属性的名字(String),另外一个是它的值(Object)
Session常用方法
Session文档
HttpSession (Java™ EE 7 Specification APIs) (oracle.com)
getAttribute(String name)
- 获取指定名称的属性值setAttribute(String name, Object value)
- 设置指定名称的属性值removeAttribute(String name)
- 移除指定名称的属性值getId()
- 获取会话IDgetCreationTime()
- 获取会话创建时间getLastAccessedTime()
- 获取会话最后访问时间setMaxInactiveInterval(int interval)
- 设置会话的最大不活动时间间隔getMaxInactiveInterval()
- 获取会话的最大不活动时间间隔invalidate()
- 使会话无效isNew()
- 判断会话是否为新创建的
Session基本使用
-
创建和获取session, API一样
HttpSession hs = request.getSession()
第 1 次调用是创建 Session 会话, 之后调用是获取创建好的 Session 对象 -
向session添加属性
hs.setAttribute(String name,Object val);
-
从session获取某个属性
Object obj=hs.getAttribute(String name);
-
从 session 删除调某个属性
hs.removeAttribute(String name);
-
判断是不是刚创建出来的 Session
hs.isNew();
-
获取session的会话ID值
hs.getId();
session 底层实现机制
原理分析图(一图胜千言)
针对每个会话都有一个Session。
getSession()
方法是session创建的核心,极其重要!
它先判断浏览器是否带有jsessionid
这个cookie数据:
- 如果没有携带:就直接创建session,并且分配一个
jsessionid
,jsessionid
和session的管理通过一个Map结构维护; - 如果携带了:
- 如果不存在
id=jsessionid
的对象:就创建session,同时分配id; - 如果存在
id=jsessionid
的对象:就直接进行操作。
- 如果不存在
如果服务器在本次会话中创建了session,就返回Set-Cookie:jsessionid=xxx
。
演示创建session
-
需求: 演示 Session 底层实现机制-创建和读取 Session
-
创建
CreateSession.java
package com.hspedu.session; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; import java.io.PrintWriter; /** * @ClassName CreateSession * @Description 演示Session的创建 * @Author zephyr * @Date 2023/3/11 14:16 * @Version 1.0 */ @WebServlet(name = "CreateSession", value = "/createSession") public class CreateSession extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("================CreateSession 被调用================"); //1. 获取session,同时也可能创建session HttpSession session = request.getSession(); //2. 获取sessionId System.out.println("当前sessionId = " + session.getId()); //3. 给session存放数据 session.setAttribute("email", "zs@qq.com"); //4. 给浏览器发送回复 response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); writer.println("<h1>创建Session成功</h1>"); writer.flush(); writer.close(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
发送请求的时候没有携带JsessionId
,服务器收到之后为之创建一个JsessionId
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rJQKggQL-1678685554206)(https://img.jing10.top/uPic/20230311image-20230311144608335.png)]
并且在响应头里返回这个Set-Cookie: JESESSION=xxxxxxx
然后该JsessionId
就被存储在了浏览器的Cookie中
现在如果我们再次向客户端发起请求,携带了刚刚的JsessionId
,那么客户端就不会再为我们创建的新的session,而是使用与JsessionId
对应的session。并且,返回响应时也不会Set-Cookie: JESESSION=xxxxxxx
。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hjBNVb0C-1678685554207)(https://img.jing10.top/uPic/20230311image-20230311150513169.png)]
演示读取session
package com.hspedu.session;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @ClassName ReadSession
* @Description 演示读取session
* @Author zephyr
* @Date 2023/3/11 15:10
* @Version 1.0
*/
@WebServlet(name = "ReadSession", value = "/readSession")
public class ReadSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("================ReadSession 被调用================");
//1. 获取Session,如果没有session也会创建
HttpSession session = request.getSession();
//输出sessionId
System.out.println("sessionId = " + session.getId());
//2. 读取属性
Object email = session.getAttribute("email");
if (email != null){
System.out.println("session属性 email = " + (String) email);
} else {
System.out.println("session没有email属性");
}
//给浏览器回回复
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("<h1>创建/操作session成功</h1>");
writer.flush();
writer.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
Session实现原理动画
服务器是如何实现一个 session 为一个用户浏览器服务的
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 生命周期-应用实例
- 需求:代码演示说明Session的生命周期
createSession2.java
package com.hspedu.session;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @ClassName CreateSession2
* @Description TODO
* @Author zephyr
* @Date 2023/3/11 15:35
* @Version 1.0
*/
@WebServlet(name = "CreateSession2", value = "/createSession2")
public class CreateSession2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("================CreateSession2 被调用================");
//获取Session,如果没有session也会创建
HttpSession session = request.getSession();
//输出session的id
System.out.println("sessionId = " + session.getId());
//设置生命周期为60s
session.setMaxInactiveInterval(60);
//设置两个属性
session.setAttribute("u", "zephyr666");
//给浏览器发送回复
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("<h1>创建session成功,生命周期60s</h1>");
writer.flush();
writer.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
ReadSession2.java
package com.hspedu.session;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Time;
/**
* @ClassName ReadSession2
* @Description TODO
* @Author zephyr
* @Date 2023/3/11 15:37
* @Version 1.0
*/
@WebServlet(name = "ReadSession2", value = "/readSession2")
public class ReadSession2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("================ReadSession2 被调用================");
//获取Session
HttpSession session = request.getSession();
//输出session的id
System.out.println("sessionId = " + session.getId());
//获取session的属性
Object u = session.getAttribute("u");
if (u != null){
System.out.println("u = " + u);
} else {
System.out.println("读取不到session属性u");
}
//给浏览器回回复
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("<h1>读取session成功</h1>");
writer.flush();
writer.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
解读:Session 的生命周期
- 指的是两次访问 session 的最大间隔时间
- 如果你在 session 没有过期的情况下,操作 session, 则会重新开始计算生命周期
- session 是否过期,是由服务器来维护和管理
- 如我们调用了
invaliate()
会直接将该 session 删除/销毁- 如果希望删除 session 对象的某个属性, 使用
removeAttribute("xx")
DeleteSession.java
package com.hspedu.session;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
/**
* @ClassName DeleteSession
* @Description TODO
* @Author zephyr
* @Date 2023/3/11 17:26
* @Version 1.0
*/
@WebServlet(name = "DeleteSession", value = "/DeleteSession")
public class DeleteSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
// 让 Session 会话立即超时
session.invalidate();
response.setContentType("text/html;charset=utf-8"); // 先获取 Session 对象
response.getWriter().write("Session 已经设置为超时");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
Session 经典案例-防止非法进入管理页面
作业布置
-
需求说明: 完成防止用户登录管理页面应用案例(如图)
-
说明:
- 只要密码为
666666
, 我们认为就是登录成功 - 用户名不限制
- 如果验证成功,则进入管理页面
ManageServelt.java
,否则进入error.html
- 如果用户直接访问
ManageServet.java
, 重定向到到userlogin.html
- 只要密码为
作用讲评
-
创建
userlogin.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户登录</title></head> <body> <h1>用户登录</h1> <form action="/cs/loginCheck" method="post"> 用户名:<input type="text" name="username"/><br/><br/> 密 码:<input type="password" name="password"><br><br/> <input type="submit" value="登录"></form> </body> </html>
-
创建
LoginCheckServlet.java
package com.hspedu.session.homework; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; /** * @ClassName LoginCheckServlet * @Description 检测用户名和密码是否正确,正确则跳转到manage页面,错误则返回error.html * @Author zephyr * @Date 2023/3/13 11:12 * @Version 1.0 */ @WebServlet(name = "LoginCheckServlet", value = "/loginCheck") public class LoginCheckServlet extends HttpServlet { @Override protected void doGet(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); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
ManageServlet.java
package com.hspedu.session.homework; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; import java.io.PrintWriter; /** * @ClassName ManageServlet * @Description 管理员页面。通过session,如果已经登录过就可以直接访问,如果没有登陆过则重定向到登录页面。 * @Author zephyr * @Date 2023/3/13 11:15 * @Version 1.0 */ @WebServlet(name = "ManageServlet", value = "/manage") public class ManageServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("================ManageServlet 被调用================"); //判断该用户是否登陆过 HttpSession session = request.getSession(); Object loginuser = session.getAttribute("loginuser"); if (loginuser == null){ //重新登陆 response.sendRedirect(request.getContextPath() + "/userlogin.html"); } else { response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); writer.println("<h1>用户管理页面</h1>"); writer.println("欢迎你,管理员: " + loginuser.toString()); writer.flush(); writer.close(); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }