当前位置: 代码迷 >> 综合 >> JAVA WEB DAY 04_Cookie & HttpSession 会话
  详细解决方案

JAVA WEB DAY 04_Cookie & HttpSession 会话

热度:83   发布时间:2024-02-19 20:11:14.0

文章目录

  • 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 浏览器:
  1. Windows系统下,cookie存储路径:
C:\Users\用户名\AppData\Local\Google\Chrome\UserData\Default\
  1. Mac系统,cookie存储路径:
~/Library/Application Support/Google/Chrome/Default
  1. Linux系统,cookie存储路径:
~/.config/google-chrome

06 Cookie 技术运行原理[★★]

  • Cookie 技术运行原理:
  1. 浏览器第一次访问服务器没有 cookie 数据
  2. 服务器端创建 Cookie 对象封装数据并以响应头形式放回给浏览器(程序员操作)
  3. 浏览器接收到 cookie 之后会将它保存到本地的文件中
  4. 浏览器再次访问服务器时会将本地 Cookie 数据以请求头形式携带给服务器
  5. 服务器可以将读取到浏览器发送的 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中包含非法字符?

  1. 先对包含非法字符的字符串进行URL编码
  2. 将编码后的结果作为Cookie的值返回给浏览器
  3. 服务器读取到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信息?
  1. 创建一个同名的Cookie对象:有效路径要一致,值无所谓
  2. 设置过期时间为0
  3. 返回给浏览器端即可

Cookie 小结

  • Cookie 的创建和返回
  1. 创建 Cookie 对象:封装数据
    Cookie c = new Cookie("name","value");
  2. 设置过期时间
    c.setMaxAge(600);
  3. 设置有效路径
    c.setPath(request.getContextPath()+"/子路径");
  4. 返回给浏览器
    response.addCookie(c);

  • 服务器端读取Cookie数据
  1. 调用请求对象方法获取Cookie数组
    Cookies cookies = request.getCookies();
  2. 遍历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之间共享
  • 应用场景
    用来保存会话过程产生的数据:可以在同一个会话中在多个Serv

14 session使用演示[★★★★]

使用session保存会话数据的步骤

  1. 调用请求对象的getSession方法获取会话域对象
  2. 调用会话域对象的方法存储键值对数据: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. 浏览器第1次访问没有会话ID
  2. 服务器第一次调用请求对象的getSession方法时就会为该会话分配一小块内存区域并指定一个会话Id
  3. 服务器会将会话ID以Cookie形式返回给浏览器端,浏览器就会将Cookie保存到本地
  4. 浏览器再次访问服务器时就会将会话ID以请求头形式发送给服务器
  5. 服务器根据会话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 [★★★]

如何实现浏览器关闭还可以再访问服务器上没有过期的信息?

  1. 创建 Cookie 对象:用来封装会话 ID Cookie 的名字必须是 JSESSIONID
  2. 设置过期时间为10分
  3. 返回 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 设置会话过期时间[★★★]

设置会话过期时间的三种方式

  1. 设置最大非活动间隔时间:setMaxInactiveInterval(int time);
  2. 通过配置文件web.xml配置:单位分钟
    <session-config>
    ??<session-timeout>1</session-timeout>
    </session-config>
  3. 立即销毁会话: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完成,程序员不用理会,只需要保证对象必须实现序列化的接口。

  • 演示步骤
  1. 如果一个会话中的对象要正确的钝化,必须要实现序列化接口
  2. 向会话域中保存Product对象
  3. 在另一个Servlet中取出Product对象输出看有没有数据
  4. 在tomcat中正常关闭服务器,观察work目录下是否有序列化的文件
  5. 重启tomcat服务器,观察work目录下变化
  6. 在浏览器没有关闭的情况下再读取会话域中的数据,看能够读取出来

钝化对象要实现接口: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实现步骤
  1. 使用昨天的代码实现验证码的绘制
  2. 将随机产生的字符串放在会话域中
  3. 用户登录的时候提交验证码的字符串
  4. 比较表单提交的字符串是否与会话域中的字符串相等,如果相等则验证成功
  5. 登录一次以后删除会话域中的验证码字符串
  6. 登录成功以后保存用户的信息到会话域中,并且跳转到WelcomeServlet
  • WelcomeServlet实现步骤
  1. 从会话域中取出用户信息
  2. 判断用户是否正常登录,如果是非法用户则跳转到登录页面
  3. 正常登录,则显示用户信息并在页面上输出一个注销的连接,点注销跳转到LogoutServlet
  • LogoutServlet实现步骤
  1. 让会话立刻过期
  2. 显示您已经成功退出
  • 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就能找到对应的内存区域:就可以对该区域数据进行增删改查操作
  相关解决方案