文章目录
- Cookie和HttpSession会话
-
- 目标
- 01 会话概述 [★★]
- 02 会话技术概述[★★]
- 03 Cookie 概述和应用场景[★★★]
- 04 Cookie 使用演示[★★★]
- 05 如何查看 Cookie 信息[★]
- 06 Cookie 技术运行原理[★★]
- 07 设置 Cookie 过期时间[★★★]
- 08 服务器端读取 Cookie 数据[★★★]
- 09 设置 Cookie 的有效路径[★★★]
- 10 Cookie 案例-实现自动登录[★★★★]
- 11 Cookie 中使用非法字符[★★★]
- 12 删除 Cookie [★★★]
- 13 session 概述和应用场景[★★]
- 14 session使用演示[★★★★]
- 15 session 技术运行原理[★★]
- 16 session 常用方法演示[★★★]
- 17 session 常见问题[★★]
- 18 保存会话ID [★★★]
- 19 设置会话过期时间[★★★]
- 20 Session & Cookie 小结[★★★]
- 21 会话的钝化与激活[★]
- 22 URL重写-禁用 Cookie 的处理[★]
- 23 session 之验证码案例[★★★★]
- 24 Servlet 三个作用域总结[★★★★]
-
- 24_01 作用域的创建和销毁
- 24_02 作用域共同的方法
- 总结
Cookie和HttpSession会话
目标
- 能够说出会话的概念
- 能够说出cookie的概念
- 能够创建、发送、接收、删除 cookie
- 能够说出cookie执行原理
- 能够说出session的概念
- 能够获取 session 对象、添加、删除、获取 session 中的数据
- 能够完成登录验证码案例
01 会话概述 [★★]
- B/S 结果会话概念:
当用户在浏览器中输入服务器地址,第一次访问服务器,会话就开始。用户多次发送请求给服务器,服务器做响应,这就是会话过程。当用户关闭浏览器,或服务器会话过期,会话就结束。
- 会话执行时间
会话开始 | 会话过程 | 会话结束 |
---|---|---|
浏览器第一次访问服务器 | 期间的多次请求 | 浏览器关闭 |
02 会话技术概述[★★]
- 会话技术的作用
用来保存会话过程产生的数据
每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,程序要想办法为每个用户保存这些数据。
HTTP是 “无状态” 协议:服务器不记录上次请求的内容是什么用户是谁,因此如果判断两次连接是否是同一用户,就需要使用 会话跟踪 技术来解决。
- 会话技术
会话技术 | 概述 |
---|---|
Cookie | 客户端会话技术:会话数据保存浏览器端 |
Session | 服务器端会话技术:会话数据保存在服务器端 |
03 Cookie 概述和应用场景[★★★]
Cookie 概念:
- 保存在浏览器端的一个小文件
Cookie 作用:
- 用来保存服务器返回的数据
- Cookie 的应用场景
04 Cookie 使用演示[★★★]
使用 Cookie 保存会话数据的步骤:
1.创建 Cookie 对象:封装要保持的数据:Cookie cookie = new Cookie("键","值");
2.调用响应对象的方法将 Cookie 返回给浏览器:response.addCookie(cookie);
Cookie 类常用方法:
String getName()
:获取 Cookie 名字
String getValue()
:获取 Cookie 值返回 Cookie 的方法:
response.addCookie(cookie);
- 需求:使用 Cookie 保存会话产生的数据;在 Servlet 中创建一个 Cookie(“username”,“ntt”),并且写到浏览器端
- 实例代码
@WebServlet(urlPatterns = "/set")
public class SetCookieServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置内容类型和编码response.setContentType("text/html;charset=utf-8");// 获得字符打印流PrintWriter out = response.getWriter();out.println("往浏览器返回了一个cookie");// 1. 创建Cookie对象:用来保存数据Cookie cookie = new Cookie("username", "ntt");// 2. 将Cookie对象返回给浏览器response.addCookie(cookie);}
}
05 如何查看 Cookie 信息[★]
- 不同的浏览器Cookie信息保存的方式是不同的
- Chrome 浏览器:
- Windows系统下,cookie存储路径:
C:\Users\用户名\AppData\Local\Google\Chrome\UserData\Default\
- Mac系统,cookie存储路径:
~/Library/Application Support/Google/Chrome/Default
- Linux系统,cookie存储路径:
~/.config/google-chrome
06 Cookie 技术运行原理[★★]
- Cookie 技术运行原理:
- 浏览器第一次访问服务器没有 cookie 数据
- 服务器端创建 Cookie 对象封装数据并以响应头形式放回给浏览器(程序员操作)
- 浏览器接收到 cookie 之后会将它保存到本地的文件中
- 浏览器再次访问服务器时会将本地 Cookie 数据以请求头形式携带给服务器
- 服务器可以将读取到浏览器发送的 Cookie 数据(程序员操作)
07 设置 Cookie 过期时间[★★★]
- 如何设置 Cookie 的过期时间
通过 cookie 对象的 setMaxAge 方法设置
?整数:代表在指定的秒数过期
?负数:无效,默认值,浏览器关闭失效
?零:删除 Cookie
- 需求:在写入 Cookie 之前先设置 Cookie 过期的时间,设置为 1 分钟以后过期
- 示例代码
@WebServlet(urlPatterns = "/set")
public class SetCookieServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置内容类型和编码response.setContentType("text/html;charset=utf-8");// 获得字符打印流PrintWriter out = response.getWriter();out.println("往浏览器返回了一个cookie");// 1. 创建Cookie对象:用来保存数据Cookie cookie = new Cookie("username", "ntt");// 2. 设置Cookie的过期时间cookie.setMaxAge(60);// 2. 将Cookie对象返回给浏览器response.addCookie(cookie);}
}
08 服务器端读取 Cookie 数据[★★★]
如何在服务器端读取浏览器发送过来的 Cookie 数据?
+调用请求对象的方法获取:Cookie[] cookies = request.getCookie();
- 需求:在服务器中读取浏览器端发来的 Cookie 数据
- 步骤:
1.创建两个Servlet
2.一个往浏览器写入cookie
3.一个读取浏览器传递的cookie并显示页面上 - GetCookieServlet
@WebServlet(urlPatterns = "/get")
public class GetCookieServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置内容类型和编码response.setContentType("text/html;charset=utf-8");// 获得字符打印流PrintWriter out = response.getWriter();// 获得浏览器发送的所有Cookie对象Cookie[] cookies = request.getCookies();if (cookies != null) {
// 遍历Cookie数组for (Cookie cookie : cookies) {
// 获得Cookie的名字String name = cookie.getName();// 获得Cookie的值String value = cookie.getValue();out.println(name+"="+value+"<br>");}}}
}
09 设置 Cookie 的有效路径[★★★]
保存在浏览器端的 cookie 数据会通过请求头发送给服务器
Cookie默认的有效路径:当前项目的访问路径
如何设置 Cookie 的有效路径
- 调用 Cookie 对象的 setPath 方法设置
问题
浏览器每次请求服务器都会携带 cookie 数据吗?
- 默认情况会
-
需求:设置 cookie 有效路径
-
步骤:
1.创建一个 Servlet 写入 cookie 并设置有效路径:/day04/path
2.创建另一个 Servlet ,观察浏览器访问该Servlet时是否携带了cookie数据 -
示例代码
@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置内容类型和编码response.setContentType("text/html;charset=utf-8");// 获得字符打印流PrintWriter out = response.getWriter();out.println("返回了Cookie并设置了有效路径");// 创建Cookie对象Cookie c = new Cookie("username", "ntt");// 设置有效路径(访问路径):需要以项目访问路径开头c.setPath(request.getContextPath()+"/login");// 返回给浏览器response.addCookie(c);}
}
10 Cookie 案例-实现自动登录[★★★★]
- 需求:使用 Cookie 记录用户名何密码,实现自动登录功能
- 说明:用户第一次登录勾选了记住我,登录成功之后需要保存用户名和密码到Cookie中。用户下一次打开登录界面时,读取Cookie数据判断是否有用户名和密码,有则实现自动登录直接进入登录登录成功页面。
- 步骤:
1.接收请求参数:用户名和密码
2.判断用户名和密码是否正确
2.1 正确则判断是否选中记住我复选框
2.2 如果选中了复选框,创建Cookie封装用户名和密码并返回给浏览器,要跳转成功页面
2.3 不正确则跳转失败页面 - 示例代码
@WebServlet(urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置请求参数的编码request.setCharacterEncoding("utf-8");// 接收请求参数:用户名和密码String username = request.getParameter("username");String password = request.getParameter("password");String remember = request.getParameter("remember");// 判断用户名和密码是否正确:admin 123if ("admin".equals(username) && "123".equals(password)) {
// 复选框选中if (remember != null){
// 创建Cookie封装用户名和密码并返回给浏览器Cookie uCookie = new Cookie("username", username);uCookie.setMaxAge(7*24*3600);response.addCookie(uCookie);Cookie pCookie = new Cookie("password", password);pCookie.setMaxAge(7*24*3600);response.addCookie(pCookie);}// 用户名和密码正确则跳转到欢迎页面(Servlet):获取用户信息显示request.getRequestDispatcher("welcome").forward(request, response);return;}// 用户名和密码不正确则跳转到失败页面(html)response.sendRedirect("login.html");}
}
11 Cookie 中使用非法字符[★★★]
注:
[ ] ( ) = , " / ? @ : ;
Tomcat8可以包含中文了
如何在Cookie中包含非法字符?
- 先对包含非法字符的字符串进行URL编码
- 将编码后的结果作为Cookie的值返回给浏览器
- 服务器读取到Cookie值时需要进行URL解码:才能还原数据
- URL编码与解码相关方法
URL编码与解码相关方法 | 说明 |
---|---|
java.net.URLEncoder.encode(“字符串”,“utf-8”) | 使用指定的码表对字符串进行编码 |
java.net.URLDecoder.decode(“字符串”,“utf-8”) | 使用指定的码表对字符串进行解码 |
- 需求:在 Servlet 中创建一个 Cookie(“user”,“杰克”),并且写到浏览器端
- 示例代码
@WebServlet(urlPatterns = "/set")
public class SetCookieServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置内容类型和编码response.setContentType("text/html;charset=utf-8");// 获得字符打印流PrintWriter out = response.getWriter();out.println("往浏览器返回了一个cookie");// 1. 创建Cookie对象:用来保存数据// An invalid character [32] was present in the Cookie value// 如果cookie值包含特殊字符,则需要先对值进行URL编码String value = URLEncoder.encode("杰克","utf8");Cookie cookie = new Cookie("user", value);// 2. 设置Cookie的过期时间cookie.setMaxAge(60);// 3. 将Cookie对象返回给浏览器response.addCookie(cookie);}
}
12 删除 Cookie [★★★]
- 如何删除浏览器端的Cookie信息?
- 创建一个同名的Cookie对象:有效路径要一致,值无所谓
- 设置过期时间为0
- 返回给浏览器端即可
Cookie 小结
- Cookie 的创建和返回
- 创建 Cookie 对象:封装数据
Cookie c = new Cookie("name","value");
- 设置过期时间
c.setMaxAge(600);
- 设置有效路径
c.setPath(request.getContextPath()+"/子路径");
- 返回给浏览器
response.addCookie(c);
- 服务器端读取Cookie数据
- 调用请求对象方法获取Cookie数组
Cookies cookies = request.getCookies();
- 遍历Cookies数组,得到一个个Cookie对象
for(Cookies c : cookies) {
??c.getName(); // 获得Cookie名
??c.getValue(); // 获得Cookie值
}
- 需求:删除 Cookie
- 步骤:
1.创建一个同名的Cookie对象:有效路径要一致,值无所谓
2.设置过期时间为0
3.返回给浏览器端即可 - 示例代码
@WebServlet(urlPatterns = "/delete")
public class DeleteCookiesServlet extends HttpServlet {
@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置内容类型和编码response.setContentType("text/html;charset=utf-8");// 获得字符打印流PrintWriter out = response.getWriter();out.println("删除cookie");// 1. 创建一个同名的Cookie对象:有效路径要一致Cookie cookie = new Cookie("user", "");// 2. 设置过期时间为0cookie.setMaxAge(0);// 3. 返回给浏览器端即可response.addCookie(cookie);}
}
13 session 概述和应用场景[★★]
- session是什么:
是服务器内部的一小块内存区域,底层是Map结构
每个会话都会有自己的内存区域,不同会话之间的内存区域数据不能共享。- session的作用:
用来保存会话过程产生的数据:可以在同一个会话中在多个Servlet之间共享
- 应用场景
14 session使用演示[★★★★]
使用session保存会话数据的步骤
- 调用请求对象的getSession方法获取会话域对象
- 调用会话域对象的方法存储键值对数据:setAttribute
- 需求:使用 session 保存会话数据。在一个 SetServlet 中,向Session 中添加一件商品名:洗衣机,另一个GetServlet从Session 中取出商品并输出在网页上。使用一个浏览器存,另一个浏览器取,看能不能取出来。
- SetServlet
@WebServlet(urlPatterns = "/set")
public class SetServlet extends HttpServlet {
@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置内容类型和编码response.setContentType("text/html;charset=utf-8");// 获得字符打印流PrintWriter out = response.getWriter();out.println("往会话域中保存了数据");// 获取会话域对象HttpSession session = request.getSession();// 往会话域中存储数据session.setAttribute("product", "洗衣机");}
}
- GetServlet
@WebServlet(urlPatterns = "/getSession")
public class GetServlet extends HttpServlet {
@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置内容类型和编码response.setContentType("text/html;charset=utf-8");// 获得字符打印流PrintWriter out = response.getWriter();// 获取会话域对象HttpSession session = request.getSession();// 从会话域中获取数据Object product = session.getAttribute("product");out.println("商品是:" + product);}
}
- 查看SetServlet响应头
服务器发送了JSESSIONID的Cookie给浏览器,值就是会话ID。服务器创建了这个 Cookie 发送给浏览器
- 查看GetServlet请求头
15 session 技术运行原理[★★]
- 浏览器第1次访问没有会话ID
- 服务器第一次调用请求对象的getSession方法时就会为该会话分配一小块内存区域并指定一个会话Id
- 服务器会将会话ID以Cookie形式返回给浏览器端,浏览器就会将Cookie保存到本地
- 浏览器再次访问服务器时就会将会话ID以请求头形式发送给服务器
- 服务器根据会话ID就能找到对应的内存区域:就可以对该区域数据进行增删改查操作
16 session 常用方法演示[★★★]
- HttpSession接口方法
HttpSession接口方法 | 作用 |
---|---|
String getId() | 获得会话ID |
long getCreationTime() | 获得会话创建时间:毫秒值 |
long getLastAccessedTime() | 获得上一次访问会话域的时间:毫秒值 |
boolean isNew() | 判断是否是新的会话 |
ServletContext getServletContext() | 获得上下文对象 |
- 示例代码
@WebServlet(urlPatterns = "/method")
public class SessionMethodServlet extends HttpServlet {
@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置内容类型和编码response.setContentType("text/html;charset=utf-8");// 获得字符打印流PrintWriter out = response.getWriter();// 获取会话域对象HttpSession session = request.getSession();out.println("会话ID:" + session.getId() + "<hr>");// 会话创建时间long createTime = session.getCreationTime();// 将毫秒值转换为日期对象Date createTimeDate = new Date(createTime);// 创建日期格式化对象// 将日期对象转换为字符串:Date ==> String// 将字符串转换为日期对象:String ==> Date// 日期格式:2020-09-10 14:10:20 或 2020/09/10 14:10:20// 年:yyyy 月:MM 日 dd 时 HH 分 mm 秒 ssSimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss");String dateStr = sdf.format(createTimeDate);out.println("会话创建时间:" + dateStr + "<hr>");Date lastAccessed = new Date(session.getLastAccessedTime());dateStr = sdf.format(lastAccessed);out.println("上次访问的时间:" + dateStr + "<hr>");out.println("是否新的会话:" + session.isNew() + "<hr>");out.println("上下文域对象:" + session.getServletContext() + "<hr>");}
}
17 session 常见问题[★★]
问题:
浏览器关闭以后,还能不能得到之前会话域中的信息?
- 不会获得会话域中的数据了,因为会话ID默认在会话结束(浏览器关闭)就销毁了
如果浏览器关闭,服务器上的会话信息是否还存在?
- 还存在,服务器会话域中的数据过期时间默认是1800秒
如何让浏览器关闭还可以再访问服务器上没有过期的信息?
- 自己保持会话ID:设置过期时间
18 保存会话ID [★★★]
如何实现浏览器关闭还可以再访问服务器上没有过期的信息?
- 创建 Cookie 对象:用来封装会话 ID Cookie 的名字必须是 JSESSIONID
- 设置过期时间为10分
- 返回 Cookie 给浏览器
- 需求:实现浏览器关闭还可以再访问服务器上没有过期的信息
@WebServlet(urlPatterns = "/save")
public class SaveSessionIdServlet extends HttpServlet {
@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置内容类型和编码response.setContentType("text/html;charset=utf-8");// 获得字符打印流PrintWriter out = response.getWriter();out.println("设置会话ID过期时间");// 获取会话域对象HttpSession session = request.getSession();// 1. 创建Cookie对象:用来封装会话IDCookie cookie = new Cookie("JSESSIONID", session.getId());// 2. 设置过期时间为10分cookie.setMaxAge(600);// 3. 返回Cookie给浏览器response.addCookie(cookie);}
}
19 设置会话过期时间[★★★]
设置会话过期时间的三种方式
- 设置最大非活动间隔时间:
setMaxInactiveInterval(int time);
- 通过配置文件web.xml配置:单位分钟
<session-config>
??<session-timeout>1</session-timeout>
</session-config>
- 立即销毁会话:
invalidate()
- 需求:设置会话过期时间
- 示例代码
@WebServlet(urlPatterns = "/time")
public class SetSessionTimeServlet extends HttpServlet {
@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置内容类型和编码response.setContentType("text/html;charset=utf-8");// 获得字符打印流PrintWriter out = response.getWriter();out.println("设置会话ID过期时间");// 获取会话域对象HttpSession session = request.getSession();out.println("最大非获得间隔时间:" + session.getMaxInactiveInterval() + "<br>"); // 1800// 方式1:设置最大非活动间隔时间session.setMaxInactiveInterval(10);out.println("最大非获得间隔时间:" + session.getMaxInactiveInterval() + "<br>"); // 10out.println("会话ID:" + session.getId() + "<br>");// 方式3:立即销毁会话,一般使用在注销或退出session.invalidate();}
}
20 Session & Cookie 小结[★★★]
- Session & Cookie 小结
技术类型 | 数据存储位置 | 键值对的数据类型 | |
---|---|---|---|
Cookie | 浏览器端会话技术 | 保存在客户端的一个文件中 | 键和值都是String类型 |
Session | 服务器端会话技术 | 保存服务器的内存中 | 键是String类型 值是Object类型 |
单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
如何选择session和cookie?
- 如果数据类比较大或包含隐私数据则选择session,否则可以使用cookie
21 会话的钝化与激活[★]
问题:
浏览器关闭的时候,服务器端的会话就销毁? 不会
服务器关闭的时候,服务器端的会话就销毁? 不会
-
概述:
在正常的情况下,如果服务器关闭或重启,服务器会将所有会话域中数据(对象)以文件的方式保存到服务器的硬盘上,下次服务器重新启动的时候,读取硬盘上文件把这些对象还原。 -
会话的钝化和激活
会话的钝化:将会话域中的数据(对象)保存到文件中的过程
会话的激活:将文件中的对象数据读取到会话域中的过程
注:项目要部署在tomcat中才有效果,在idea中没有效果
在work目录下:
%CATALINA_HOME%\work\Catalina\localhost\项目名\SESSIONS.ser
钝化和激活过程由tomcat完成,程序员不用理会,只需要保证对象必须实现序列化的接口。
- 演示步骤
- 如果一个会话中的对象要正确的钝化,必须要实现序列化接口
- 向会话域中保存Product对象
- 在另一个Servlet中取出Product对象输出看有没有数据
- 在tomcat中正常关闭服务器,观察work目录下是否有序列化的文件
- 重启tomcat服务器,观察work目录下变化
- 在浏览器没有关闭的情况下再读取会话域中的数据,看能够读取出来
钝化对象要实现接口:
Serializable
22 URL重写-禁用 Cookie 的处理[★]
如何实现禁止Cookie之后还能继续访问会话域数据?
- 对URL进行重写:在URL后面拼接会话ID传递给服务器即可
- 什么是URL重写
对URL进行改写,在URL后面拼接会话ID
- URL重写相关方法
URL重写相关方法 | 说明 |
---|---|
response.encodeRedirectURL(path) | 将重定向的地址进行重写,添加一个会话ID在后面。 |
response.encodeURL(path) | 将要跳转到的地址(链接或表单地址)进行URL重写 添加一个会话ID在后面。 |
-
需求:实现浏览器禁用Cookie后仍然能够访问服务器上Session的数据
-
演示禁用Cookie后会话域数据无法共享
1.把浏览器的Cookie禁用
2.在一个Servlet1中向session中添加一个数据,重定向到Servlet2。
3.在另一个Servlet2中的session中读取数据并显示出来
4.无法得到会话域中的数据 -
URL重写演示
-
1.重定向URL重写代码演示
@WebServlet(urlPatterns = "/demo01")
public class SetServlet extends HttpServlet {
@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置内容类型和编码response.setContentType("text/html;charset=utf-8");// 获得字符打印流PrintWriter out = response.getWriter();// 获取会话域对象(第一次调用getSession方法才会分配内存区域,并分配一个会话ID)HttpSession session = request.getSession();// 创建产品对象Product product = new Product("IPone12");// 往会话域中存储数据session.setAttribute("product", product);// 重定向到demo02String url = "demo02";System.out.println("重写前:"+url);// 对要重定向的地址进行重写url = response.encodeRedirectURL(url);System.out.println("重写后:"+url);response.sendRedirect(url);}
}
- 超链接URL重写代码演示
@WebServlet(urlPatterns = "/demo01")
public class SetServlet extends HttpServlet {
@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置内容类型和编码response.setContentType("text/html;charset=utf-8");// 获得字符打印流PrintWriter out = response.getWriter();// 获取会话域对象(第一次调用getSession方法才会分配内存区域,并分配一个会话ID)HttpSession session = request.getSession();// 创建产品对象Product product = new Product("IPone12");// 往会话域中存储数据session.setAttribute("product", product);String url = "demo02";// 对超链接的地址进行重写url = response.encodeURL(url);out.println("<a href='"+url+"'>查询产品信息</a>");}
}
23 session 之验证码案例[★★★★]
- 需求:
1.用户登录的时候使用验证码进行验证。
2.登录成功后将用户信息保存到会话域中,并且跳转到 WelcomeServlet,然后在WeclcomeServlet 中读取用户信息,显示欢迎信息。在 WelcomeServlet上显示退出的链接,点退出,注销会话信息。
- LoginServlet实现步骤
- 使用昨天的代码实现验证码的绘制
- 将随机产生的字符串放在会话域中
- 用户登录的时候提交验证码的字符串
- 比较表单提交的字符串是否与会话域中的字符串相等,如果相等则验证成功
- 登录一次以后删除会话域中的验证码字符串
- 登录成功以后保存用户的信息到会话域中,并且跳转到WelcomeServlet
- WelcomeServlet实现步骤
- 从会话域中取出用户信息
- 判断用户是否正常登录,如果是非法用户则跳转到登录页面
- 正常登录,则显示用户信息并在页面上输出一个注销的连接,点注销跳转到LogoutServlet
- LogoutServlet实现步骤
- 让会话立刻过期
- 显示您已经成功退出
- LoginServlet
@WebServlet(urlPatterns = "/login01")
public class LoginServlet extends HttpServlet {
@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取请求参数(用户名,密码,验证码)String username = request.getParameter("username");String password = request.getParameter("password");String vcode = request.getParameter("vcode");// 2. 从会话域中获取验证码HttpSession session = request.getSession();String verCode = (String) session.getAttribute("verCode");// 3. 判断用户输入的验证码是否正确,正确执行第4步,否则第5步if (verCode.equalsIgnoreCase(vcode)){
// 4. 判断用户名和密码是否正确if ("admin".equals(username) && "123".equals(password)){
// 4.1 将用户信息存储到会话域中session.setAttribute("username", username);// 4.2 跳转到欢迎页面response.sendRedirect("welcome");return;}}// 5. 回到登录页面response.sendRedirect("login.html");}
}
- WelcomeServletr
@WebServlet(urlPatterns = "/welcome")
public class WelcomeServlet extends HttpServlet {
@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置内容类型和编码response.setContentType("text/html;charset=utf-8");// 获得字符打印流PrintWriter out = response.getWriter();// 从会话域中获取用户名HttpSession session = request.getSession();Object username = session.getAttribute("username");out.println("欢迎你," + username +"<br>");out.println("<a href='logout'>退出</a>");}
}
- LogoutServlet
@WebServlet(urlPatterns = "/logout")
public class LogoutServlet extends HttpServlet {
@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置内容类型和编码response.setContentType("text/html;charset=utf-8");// 获得字符打印流PrintWriter out = response.getWriter();// 获得会话域对象HttpSession session = request.getSession();// 立即销毁会话session.invalidate();out.println("你已经成功退出");}
}
24 Servlet 三个作用域总结[★★★★]
如何选择作用域
- 如果小范围的作用域能够满足需要就使用小范围的作用域
- 请求域 < 会话域 < 上下文域
24_01 作用域的创建和销毁
作用域 | 接口名 | 作用范围 | 生命周期 |
---|---|---|---|
请求域 | HttpServletRequest | 同一个请求有效 | 请求开始到请求结束 |
会话域 | HttpSession | 同一个会话有效 | 会话开始到会话结束 |
上下文域 | ServletContext | 同一应用有效 | 服务器启动到服务器关闭 |
24_02 作用域共同的方法
功能 | 方法名 |
---|---|
存放数据 | setAttribute |
获取数据 | getAttribute |
删除数据 | removeAttribute |
总结
会话:
- 浏览器第一次访问服务器会话开始,用户期间多次请求,浏览器关闭会话结束。
Cookie
- 概念:一个保存在浏览器用来保存服务器返回的数据的小文件
- 创建:
Cookie cookie = new Cookie("键","值")
- 发送:
response.addCookie(cookie)
- 接收:
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
??cookie.getName
??cookie.getValue
}
- 删除:
Cookie cookie = new Cookie("username", "");
cookie.setMaxAge(0);
response.addCookie(cookie);
- 设置有效路径:
cookie.setPath(request.getContextPath()+"/子路径");
- 执行原理:
1.浏览器第一次访问服务器没有 cookie 数据
2.服务器端创建 Cookie 对象封装数据并以响应头形式放回给浏览器(程序员操作)
3.浏览器接收到 cookie 之后会将它保存到本地的文件中
4.浏览器再次访问服务器时会将本地 Cookie 数据以请求头形式携带给服务器
5.服务器可以将读取到浏览器发送的 Cookie 数据(程序员操作)
Session
- 概念:
是服务器内部的一小块内存区域,底层是Map结构,每个会话都会有自己的内存区域,不同会话之间的内存区域数据不能共享。- 获取对象:
HttpSession session = request.getSession();
- 添加:
session.setAttribute("键","值");
- 删除:
session.invalidate();
- 获取数据:
Object 键 = session.getAttribute("键");
- 设置最大非活动间隔时间:
setMaxInactiveInterval(int time);
- 执行原理:
1.浏览器第1次访问没有会话ID
2.服务器第一次调用请求对象的getSession方法时就会为该会话分配一小块内存区域并指定一个会话Id
3.服务器会将会话ID以Cookie形式返回给浏览器端,浏览器就会将Cookie保存到本地
4.浏览器再次访问服务器时就会将会话ID以请求头形式发送给服务器
5.服务器根据会话ID就能找到对应的内存区域:就可以对该区域数据进行增删改查操作