会话技术

  • 什么是会话?这里的会话,指的是web开发中的一次通话过程,当打开浏览器,访问网站地址后,会话开始,当关闭浏览器(或者到了过期时间),会话结束。
  • 举个例子:例如,你在给家人打电话,这时突然有送快递的配送员敲门,你放下电话去开门,收完快递回来后,通话还在保持中,继续说话就行了。
  • 会话管理的作用:
    • 什么时候会用到会话管理呢?最常见的就是购物车,当我们登录成功后,把商品加入到购物车之中,此时我们无论再浏览什么商品,当点击购物车时,那些加入的商品都仍在购物车中。在我们的实际开发中,还有很多地方都离不开会话管理技术。比如,我们在论坛发帖,没有登录的游客身份是不允许发帖的。所以当我们登录成功后,无论我们进入哪个版块发帖,只要权限允许的情况下,服务器都会认识我们,从而让我们发帖,因为登录成功的信息一直保留在服务器端的会话中。在我们的实际开发中,还有很多地方都离不开会话管理技术。比如,我们在论坛发帖,没有登录的游客身份是不允许发帖的。所以当我们登录成功后,无论我们进入哪个版块发帖,只要权限允许的情况下,服务器都会认识我们,从而让我们发帖,因为登录成功的信息一直保留在服务器端的会话中。
  • 会话管理的分类:
    • 在JavaEE的项目中,会话管理分为两类。分别是:
      • 客户端会话管理技术:它是把要共享的数据保存到了客户端(也就是浏览器端)。每次请求时,把会话信息带到服务器,从而实现多次请求的数据共享。
      • 服务端会话管理技术:它本质仍是采用客户端会话管理技术,只不过保存到客户端的是一个特殊的标识,并且把要共享的数据保存到了服务端的内存对象中。每次请求时,把这个标识带到服务器端,然后使用这个标识,找到对应的内存空间,从而实现数据共享。

一、客户端会话管理技术——Cookie(重要)

1.1 cookie的认识

(1)cookie的概述

  • 它是客户端浏览器的缓存文件,里面记录了客户浏览器访问网站的一些内容。同时,也是HTTP协议请求和响应消息头的一部分
  • cookie的API详解:
    • 作用:它可以保存客户浏览器访问网站的相关内容(需要客户端不禁用Cookie)。从而在每次访问需要同一个内容时,先从本地缓存获取,使资源共享,提高效率。
    • cookie的属性 | 属性名称 | 属性作用 | 是否重要 | | —- | —- | —- | | name | cookie的名称 | 必要属性 | | value | cookie的值(不能是中文) | 必要属性 | | path | cookie的路径 | 重要 | | domain | cookie的域名 | 重要 | | maxAge | cookie的生存时间 | 重要 | | version | cookie的版本好。 | 不重要 | | comment | cookie的说明 | 不重要 |
  • cookie的细节说明:
    • Cookie有大小,个数限制。每个网站最多只能存20个cookie,且大小不能超过4kb。同时,所有网站的cookie总数不超过300个。
    • 当删除Cookie时,设置maxAge值为0。当不设置maxAge时,使用的是浏览器的内存,当关闭浏览器之后,cookie将丢失。设置了此值,就会保存成缓存文件(值必须是大于0的,以秒为单位)。

(2)cookie的常用方法

cookie和session相关的笔记 - 图1

  1. /**
  2. * 通过指定的名称和值构造一个Cookie
  3. *
  4. * Cookie的名称必须遵循RFC 2109规范。这就意味着,它只能包含ASCII字母数字字符,
  5. * 不能包含逗号、分号或空格或以$字符开头。
  6. * 创建后无法更改cookie的名称。
  7. *
  8. * 该值可以是服务器选择发送的任何内容。
  9. * 它的价值可能只有服务器才感兴趣。
  10. * 创建之后,可以使用setValue方法更改cookie的值。
  11. */
  12. public Cookie(String name, String value) {
  13. validation.validate(name);
  14. this.name = name;
  15. this.value = value;
  16. }
  • 向浏览器添加cookie

cookie和session相关的笔记 - 图2

  1. /**
  2. * 添加Cookie到响应中。此方法可以多次调用,用以添加多个Cookie。
  3. */
  4. public void addCookie(Cookie cookie);
  • 从服务器端获取cookie

cookie和session相关的笔记 - 图3

  1. /**
  2. * 这是HttpServletRequest中的方法。
  3. * 它返回一个Cookie的数组,包含客户端随此请求发送的所有Cookie对象。
  4. * 如果没有符合规则的cookie,则此方法返回null。
  5. */
  6. public Cookie[] getCookies();

1.2 cookie的使用细节:浏览器什么时候将cookie带给服务器,什么时候不带的问题

(1)相关案例

  • 创建一个Cookie,设置Cookie的path,通过不同的路径访问,从而查看请求携带Cookie的情况。
  • 案例步骤:

    • 第一步:创建javaweb工程
    • 第二步:编写 servlet ```java /**

      • Cookie的路径问题
      • 前期准备:
      • 1.在demo1中写一个cookie到客户端
      • 2.在demo2和demo3中分别去获取cookie
      • demo1的Servlet映射是 /servlet/PathQuestionDemo1
      • demo2的Servlet映射是 /servlet/PathQuestionDemo2
      • demo3的Servlet映射是 /PathQuestionDemo3 *
      • @author 黑马程序员
      • @Company http://www.itheima.com / public class PathQuestionDemo1 extends HttpServlet {

      public void doGet(HttpServletRequest request, HttpServletResponse response)

      1. throws ServletException, IOException {

      //1.创建一个Cookie Cookie cookie = new Cookie(“pathquestion”,”CookiePathQuestion”); //2.设置cookie的最大存活时间 cookie.setMaxAge(Integer.MAX_VALUE); //3.把cookie发送到客户端 response.addCookie(cookie);//setHeader(“Set-Cookie”,”cookie的值”) }

      public void doPost(HttpServletRequest request, HttpServletResponse response)

      1. throws ServletException, IOException {

      doGet(request, response); } }

/**

  • 获取Cookie,名称是pathquestion
  • @author 黑马程序员
  • @Company http://www.itheima.com */ public class PathQuestionDemo2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)

    1. throws ServletException, IOException {
    2. //1.获取所有的cookie
    3. Cookie[] cs = request.getCookies();
    4. //2.遍历cookie的数组
    5. for(int i=0;cs!=null && i<cs.length;i++){
    6. if("pathquestion".equals(cs[i].getName())){
    7. //找到了我们想要的cookie,输出cookie的值
    8. response.getWriter().write(cs[i].getValue());
    9. return;
    10. }
    11. }

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)

    1. throws ServletException, IOException {
    2. doGet(request, response);

    } }

/**

  • 获取Cookie,名称是pathquestion
  • @author 黑马程序员
  • @Company http://www.itheima.com */ public class PathQuestionDemo3 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)

    1. throws ServletException, IOException {
    2. //1.获取所有的cookie
    3. Cookie[] cs = request.getCookies();
    4. //2.遍历cookie的数组
    5. for(int i=0;cs!=null && i<cs.length;i++){
    6. if("pathquestion".equals(cs[i].getName())){
    7. //找到了我们想要的cookie,输出cookie的值
    8. response.getWriter().write(cs[i].getValue());
    9. return;
    10. }
    11. }

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)

    1. throws ServletException, IOException {
    2. doGet(request, response);

    } } ```

    • 第三步:配置servlet ```xml PathQuestionDemo1 com.itheima.web.servlet.pathquestion.PathQuestionDemo1 PathQuestionDemo1 /servlet/PathQuestionDemo1

PathQuestionDemo2 com.itheima.web.servlet.pathquestion.PathQuestionDemo2

PathQuestionDemo2 /servlet/PathQuestionDemo2

PathQuestionDemo3 com.itheima.web.servlet.pathquestion.PathQuestionDemo3

PathQuestionDemo3 /PathQuestionDemo3 ```

  • 第四步:部署工程
  • 第五步:测试
    • 测试结果:通过分别运行PathQuestionDemo1,2和3这3个Servlet,我们发现由demo1写Cookie,在demo2中可以取到,但是到了demo3中就无法获取了,如下图所示:

cookie和session相关的笔记 - 图4
cookie和session相关的笔记 - 图5
cookie和session相关的笔记 - 图6

  1. - 路径问题及分析和总结
  2. - demo2demo3谁能获取到cookie?
  3. - 答案:
  4. - demo2能获取到,demo3获取不到。
  5. - 分析:
  6. - 首先,我们要知道如何确定一个cookie?那就是使用cookie的三个属性组合:domain+path+name,这里面,同一个应用的domain是一样的,在我们的案例中都是localhost。并且我们取的都是同一个cookie,所以name也是一样的,都是pathquestion。那么,不一样的就只能是path了。但是我们没有设置过cookiepath属性,这就表明path是有默认值的。接下来,我们打开这个cookie 来看一看,在IE浏览器访问一次PathQuestionDemo1这个Servlet
  7. - cookie中的内容:

cookie和session相关的笔记 - 图7

二、服务端会话管理技术——HttpSession

2.1 HttpSession的认识

(1)HttpSession的概述

  • HttpSession对象,它是一个Servlet规范中提供的一个接口,该接口的实现由Servlet规范的实现提供。我们使用的tomcat服务器,它对Servlet规范进行了实现,所以HttpSession接口的实现由Tomcat提供,该对象用于提供一种通过多个页面请求或者访问网站来标识用户并存储有关该用户的信息的方法。简单的说就是一个服务器端会话对象,用于存储用户的会话数据的。
  • 同时,它也是Servlet规范中四大域对象之一的会话域对象。并且它也是用于实现数据共享的。但它与我们之前讲解的应用域和请求域是有区别的。