会话技术(Session、Cookie)详细介绍

桃扇骨 2024-04-01 12:50 171阅读 0赞

会话技术

  • request:接收请求

    • 接收请求行

      • 接收请求方式:request.getMethod()
      • 接收项目路径:request.getContextPath()
    • 接收请求头

      • request.getHeader(String name)
    • 接收请求参数

      • 中文参数:

        • get方式:不乱码。因为tomcat8.5已经帮我们解决了
        • post方式:乱码: request.setCharacterEncoding(“utf-8”)
      • 接收单值的:String value = request.getParameter(String name)
      • 接收多值的:String[] values = request.getParameterValues(String name)
      • 接收所有: Map map = request.getParameterMap()
    • 其它作用:

      • 是一个域对象

        • 何时创建:一次请求开始
        • 何时销毁:一次请求结束
        • 作用范围:一次请求期间
      • 可以实现请求转发

        • request.getRequestDispatcher(“/login.jsp”).forward(req,resp)
  • response:用于设置响应的

    • 设置响应行

      • 设置响应状态码:response.setStatus(int code)
    • 设置响应头

      • response.setHeader(String name,String value)
    • 设置响应体

      • 字节流方式 :response.getOutputStream()
      • 字符流方式:

        • 处理中文响应乱码:response.setContentType(“text/html;charset=utf-8”)
        • response.getWriter().print(String string)
    • 重定向跳转:response.sendRedirect(“/test/index.jsp”)
  • 请求转发和重定向的区别:

    • 重定向 2次请求; 请求转发 1次请求
    • 重定向 地址栏会变; 请求转发 地址栏不变
    • 重定向 是浏览器跳转; 请求转发 是服务器跳转
    • 重定向 可以跳转任意地址; 请求转发只能跳转项目内的资源
  • 什么时候用请求转发?什么时候用重定向?

    • 如果跳转时有数据要传递,要使用请求转发;
    • 否则可以使用重定向

一、会话技术介绍

目标

  • 了解什么是会话
  • 了解什么是会话技术
  • 理解会话技术的特点【重点】

讲解

1. 什么是会话

“会话”是引用了现实生活中的概念。

现在生活中的“会话”,比如:电话通话。双方建立连接之后,可以有多次应答,最后断开结束会话

我们所说的“会话”,双方指的是客户端和服务端

  • 会话开始:客户端和服务端建立连接
  • 会话过程:可以有多次请求和响应
  • 会话结束:关闭浏览器,会话结束
2. 什么是会话技术

会话技术:用于存储会话过程中的一些数据的技术,用于在同一会话内部共享数据的技术

会话技术的特点:

  • 会话技术是存储数据的技术
  • 会话技术存储的数据:在一个会话内多次请求之间,数据要共享
  • 会话技术存储的数据:在不同会话之间,数据应该相互独立、互不干扰的

简单来说:

  • 我访问京东,我跟京东的会话,添加的购物车数据,是我的
  • 你访问京东,你跟京东的会话,添加的购物车数据,是你的
  • 两个人的数据,应该互不干扰
3. 有哪些会话技术
  • Cookie:客户端的会话技术,会话数据存储在客户端浏览器

    • 不安全;只能存储字符串
    • 服务器压力小
  • session:服务端的会话技术,会话数据存储在服务端。

    • 更安全;可以存储任意类型的对象
    • 服务器压力大
目标
  • 了解Cookie技术的使用过程
  • 使用Cookie的主要API,完成Cookie的创建、发送、接收
讲解

在这里插入图片描述

  • 创建Cookie,返回给客户端

    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;

    @WebServlet(urlPatterns=”/createCookie”)
    public class Demo01CreateCookieServlet extends HttpServlet {

    1. @Override
    2. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    3. //1. 创建一个Cookie: name和value都不支持中文、空格、特殊符号,建议只使用字母、数字
    4. Cookie cookie = new Cookie("name", "ErGe");
    5. //2. 把Cookie添加到response里
    6. // 最终会把Cookie放在响应头里,返回给客户端 Set-Cookie: name=ErGe
    7. response.addCookie(cookie);
    8. //问题:能创建多少个Cookie返回给客户端?可以创建任意个,但是浏览器只能接收有限数量的Cookie
    9. // 按照Servlet规范:一个浏览器为每个服务器支持20个Cookie,一个浏览器总共支持300个Cookie;
    10. //    每个Cookie限制4KB
    11. Cookie cookie2 = new Cookie("sex", "male");
    12. response.addCookie(cookie2);
    13. }
    14. @Override
    15. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    16. this.doPost(request, response);
    17. }

    }

  • 接收客户端携带的Cookie

    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;

    @WebServlet(urlPatterns=”/getCookie”)
    public class Demo02GetCookieServlet extends HttpServlet {

    1. @Override
    2. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    3. //1. 接收客户端携带到服务端的Cookie
    4. // 浏览器会把Cookie自动放到请求头里,携带到服务端:Cookie: name=ErGe
    5. Cookie[] cookies = request.getCookies();
    6. for (Cookie cookie : cookies) {
    7. System.out.println(cookie.getName() +": " + cookie.getValue());
    8. }
    9. }
    10. @Override
    11. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    12. this.doPost(request, response);
    13. }

    }

演示操作的步骤
  • 打开浏览器,先清除浏览器缓存:ctrl + shift + delete
  • 再访问:http://localhost:8080/demo/createCookie

    • Servlet里创建了Cookie,把Cookie返回给了浏览器
    • 浏览器会自动接收并保存Cookie数据
  • 然后访问:http://localhost:8080/demo/getCookie

    • 浏览器发请求时,会自动把Cookie携带到服务端
    • Servlet里的代码接收了Cookie,并把Cookie输出到了idea的控制台
  • 最终实现了:一次会话内、多次请求之间的数据共享
目标
  • 了解Cookie的有效期
  • 能说出Cookie的默认有效期
  • 能设置Cookie的有效期
讲解
  • 浏览器接收到Cookie之后,会存储多长时间。这个时间叫有效期
  • Cookie数据并非永久存储的,那么可以存储到什么时候
  • 一次会话期间(只要浏览器一关闭,Cookie就失效了)
  • 演示操作的步骤:

    1. 打开浏览器,先清除缓存
    2. 访问http://localhost:8080/demo/createCookie:

      • 服务端会创建Cookie,返回给客户端;
      • 浏览器接收并存储Cookie
    3. 再访问http://localhost:8080/demo/getCookie:Cookie还是有效的

      1. 浏览器发请求时,会自动把Cookie携带到服务端
      2. 服务端可以接收到 Cookie
    4. 关闭浏览器,再打开后访问 http://localhost:8080/demo/getCookie:Cookie已经失效了

      1. 浏览器发请求时,已经没有Cookie
      2. 服务端再接收并输出,会报空指针异常
  • 设置有效期之后,在到期之前Cookie始终有效,无论浏览器是否关闭重启;
  • 强制清除浏览器的缓存:一定可以清除Cookie

    cookie.setMaxAge(int 秒数)

代码示例
  • 修改Demo01CreateCookieServlet的代码

    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;

  1. @WebServlet(urlPatterns="/createCookie")
  2. public class Demo01CreateCookieServlet extends HttpServlet {
  3. @Override
  4. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  5. //1. 创建一个Cookie: name和value都不支持中文、空格、特殊符号,建议只使用字母、数字
  6. Cookie cookie = new Cookie("name", "ErGe");
  7. // 设置cookie的有效期为60秒
  8. cookie.setMaxAge(60);
  9. response.addCookie(cookie);
  10. //2. 这个cookie,没有设置有效期
  11. Cookie cookie2 = new Cookie("sex", "male");
  12. response.addCookie(cookie2);
  13. }
  14. @Override
  15. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  16. this.doPost(request, response);
  17. }
  18. }

演示过程:

  • 修改Demo01CreateCookieServlet

    • 给名称为name的Cookie设置有效期为60秒
    • 名称为sex的Cookie,不设置有效期,有效期仍然是默认的一次会话(浏览器关闭就失效)
    • 重启Tomcat
  • 在浏览器里输入地址:http://localhost:8080/demo/setCookie

    • 服务端创建了两个Cookie,都返回给了浏览器。这两个Cookie分别是:

      • 第一个Cookie:名称是name,值是ErGe,有效期:60秒
      • 第二个Cookie:名称是sex,值是male,有效期:默认的
    • 浏览器接收到Cookie后,会自动保存cookie
  • 在60秒内:两个Cookie都有效

    • 浏览器访问 http://localhost:8080/demo/getCookie

      • 浏览器会把两个Cookie都自动携带到服务端
      • 服务端可以接到这两个Cookie
  • 在60秒内:关闭重启浏览器,名称为name的Cookie仍有效;名称为sex的Cookie失效了

    • 浏览器访问 http://localhost:8080/demo/getCookie

      • 浏览器会把还有效的Cookie(名称为name的)自动携带到服务端
      • 服务端只能接到这一个名称为name的Cookie
  • 60秒之后:两个Cookie都失效了

    • 浏览器访问 http://localhost:8080/demo/getCookie

      • 服务端接收不到,循环所有Cookie并输出,会报错
小结
  • Cookie默认有效期:一次会话结束
  • 设置Cookie有效期:cookie.setMaxAge(秒)

    • 在cookie过期之前,无论是否关闭重启浏览器,Cookie始终有效
    • 在cookie到期之后,会自动失效
  • 注意:无论什么样的Cookie,只要清除浏览器缓存,都可以清除掉
目标
  • 能够获取客户端携带的Cookie数据
讲解
API部分
  • 接收Cookie:Cookie[] cookies = request.getCookies()。如果接收不到,返回值是null
  • 从Cookie里获取数据:每个Cookie可以理解为是一个键值对数据(还有其它附加数据)

    • cookie.getName():获取Cookie的名称
    • cookie.getValue():获取Cookie的值
封装一个工具类
  • 用于获取指定名称的那个Cookie的值

    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServletRequest;

  1. public class CookieUtils {
  2. public static String getCookieValue(HttpServletRequest request, String name){
  3. Cookie[] cookies = request.getCookies();
  4. if (cookies != null) {
  5. for (Cookie cookie : cookies) {
  6. if (name.equals(cookie.getName())) {
  7. return cookie.getValue();
  8. }
  9. }
  10. }
  11. return null;
  12. }
  13. }

使用工具类,获取某个名称的Cookie值

  1. import javax.servlet.ServletException;
  2. import javax.servlet.annotation.WebServlet;
  3. import javax.servlet.http.Cookie;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. /**
  9. * 接收Cookie,封装一个工具类
  10. */
  11. @WebServlet(urlPatterns="/getcookie2")
  12. public class Demo05GetCookieServlet extends HttpServlet {
  13. @Override
  14. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  15. //要求:客户端发请求会把Cookie携带过来,但是我们只要获取其中名称为name的Cookie值
  16. //要求:客户端发请求会把Cookie携带过来,但是我们只要获取其中名称为sex的Cookie值
  17. String name = "name";
  18. String value = CookieUtils.getCookieValue(request, name);
  19. /*Cookie[] cookies = request.getCookies();
  20. if (cookies != null) {
  21. for (Cookie cookie : cookies) {
  22. if (name.equals(cookie.getName())) {
  23. value = cookie.getValue();
  24. break;
  25. }
  26. }
  27. }*/
  28. System.out.println("得到Cookie值是:" + value);
  29. }
  30. @Override
  31. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  32. this.doPost(request, response);
  33. }
  34. }

三、session

1. session的使用过程

目标
  • 了解session的使用过程
讲解
使用流程

在这里插入图片描述

使用示例

在任何Servlet里,如果要使用session对象,只需要两步:

  1. 得到一个session对象 :HttpSession session = request.getSession()

    • 如果当前会话有session对象,就直接返回这个对象
    • 如果当前会话没有session对象,就会创建一个session对象
  2. 使用session存取数据:域对象的方法

代码演示的步骤:

  1. 打开浏览器,先清除缓存
  2. 访问 http://localhost:8080/demo/session1

    • 服务端执行request.getSession()

      • 当前会话还没有session对象,这个方法会创建一个session
      • 然后tomcat会把session的id放到Cookie里,设置到response,最终会返回给浏览器
    • 把名称为name的数据存储到session里
    • 浏览器接收到Cookie:JSESSIONID=session的id
  3. 再访问 http://localhost:8080/demo/session2

    • 浏览器会自动把CookieJSESSIONID=session的id携带到服务端
    • 服务端执行request.getSession()

      • 当前会话已经有session对象,tomcat会接收Cookie中的JSESSIONID,找到当前会话的session
      • 把找到的session返回给我们
    • 我们可以从session里得到名称为name对应的数据

    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;

    /**

    • request.getSession():
    • 如果本次请求所属的会话,已经有session对象了:直接得到这个session对象
    • 如果本次请求所属的会话,还没有session对象: 方法会创建一个新的session对象
      *
    • 问题:session里的数据,什么情况下会找不到?
    • 如果session对象没有了,数据就找不到了
    • 如果Cookie(JSESSIONID)没有了,数据也找不到了
      *
    • 实际场景是:
      1. 如果在浏览器里打开新标签页,可以找到数据(客户端有JSESSIONID,服务端有session对象)
      1. 如果清除了浏览器缓存,再访问 找不到数据(客户端没有JSESSIONID了)
      1. 如果关闭重启了浏览器,再访问 找不到数据(客户端没有JSESSIONID了)
      1. 如果换一个浏览器访问, 找不到数据(客户端没有JSESSIONID)
      1. 如果服务端的session对象销毁了,找不到数据
      1. 如果服务器关闭重启了,session有没有销毁呢?
    • 如果是正常关闭重启,session没有销毁
    • 如果是非正常关闭重启,session会销毁掉
      *
    • 但是idea修改了tomcat的配置,每次重启都会强制销毁session对象
      /
      @WebServlet(urlPatterns=”/session1”)
      public class Demo01SessionServlet extends HttpServlet {

      @Override
      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

      //1.得到一个session对象
      HttpSession session = request.getSession();
      System.out.println(“/session1里的id:” + session.getId());

      //2.把数据存储到session里
      session.setAttribute(“name”, “tom”);

      //手动销毁session对象
      session.invalidate();
      session = request.getSession();
      System.out.println(“/session1里销毁后重新获取的id:” + session.getId());
      }

      @Override
      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

      this.doPost(request, response);
      }
      }

    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;

  1. @WebServlet(urlPatterns="/session2")
  2. public class Demo02SessionServlet extends HttpServlet {
  3. @Override
  4. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  5. //1. 得到一个session对象
  6. HttpSession session = request.getSession();
  7. //2. 从session里取出数据
  8. Object name = session.getAttribute("name");
  9. System.out.println("session2里取数据:" + name);
  10. }
  11. @Override
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. this.doPost(request, response);
  14. }
  15. }

2. 获取session对象

目标
  • 能够得到一个session对象
  • 能够判断什么情况是创建新session、什么情况会获取旧session
讲解
  • 获取session对象:request.getSession()
  • 什么时候会创建新的session?

    • 客户端没有JSESSIONID
    • 客户端有JSESSIONID,但是服务端没有对应的session对象了
  • 什么时候会获取旧的session?

    • 客户端有JSESSIONID,并且服务端有对应的session对象
  • 什么时候session里的数据会找不到?

    • 只要找不到旧的session对象,就找不到里边的数据了
    • 浏览器关闭了,重启了,清除缓存了,换了浏览器
    • 服务器非正常关闭了

发表评论

表情:
评论列表 (有 0 条评论,171人围观)

还没有评论,来说两句吧...

相关阅读

    相关 会话技术

    会话技术 解决这个客户端和服务端数据的共享问题 HTTP 他是一种无状态协议,所以我们要通过会话技术,来解决多次请求时数据的共享 (一)客户端会话技术C...

    相关 会话技术的概述 会话技术的概述

    会话技术的概述 会话技术的概述 什么是会话 会话简单理解为:用户打开一个浏览器,点击多个超链接访问服务器的web资源,然后关闭浏览器,整个过程称为是一次会话。 为什么要