Cookie 和 Session

Cookie

什么是Cookie

  • Cookie是一个类,只能存储键值对。只有下面一个构造方法

Cookie的创建,负责创建Cookie并发送给客户端并通知浏览器保存

实验的环境

  • CookieServlet
package com.atguigu.web;

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

public class CookieServlet extends BaseServlet{


    protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      //1.创建Cookie对象
      Cookie cookie = new Cookie("key1","value1");
      Cookie cookie1 = new Cookie("key2","value2");
      Cookie cookie2 = new Cookie("key3","value3");
      //2.通知客户端保存Cookie
      resp.addCookie(cookie);
      resp.addCookie(cookie1);
      resp.addCookie(cookie2);
      //3.往客户端打印内容
      resp.getWriter().write("cookie创建成功了");
    }
}

**由BaseServlet实现对CreateCookie的发射调用

  • cookie的查看:在浏览器中按f12:


    需要解决的问题:

  • 解决


    问题2:我们的cookie对象是怎样就写到了浏览器当中呢?其中的原理是怎样的?
    Cookie对象是通过HTTP响应头字段中的Set-Cookie响应头字段发送给浏览器的。当服务器向客户端发送响应时,它会在响应头中添加一个或多个Set-Cookie字段。
    当我们的服务器通知客户端进行保存,我们的浏览器将会保存响应头的cookie或者更新他的值

  • cookie创建和保存的原理

  • 可以创建多个并保存多个cookie对象

Cookie的获取

  • 演示cookie获取
    客户端有了cookie后,每次请求都发送给服务器。具体怎样发送的呢?
  • cookie获取原理
  • 前提是浏览器中已经存在cookie
  • 调用CookieServlet中的getCookie方法
//服务器获取客户端的cookie
    protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取服务器发送过来的cookie
        final Cookie[] cookies = req.getCookies();
        //2.getName获取cookie的key
        //3.getValue获取cookie的value
        for (Cookie cookie : cookies) {
           resp.getWriter().write("Cookie["+cookie.getName()+"="+cookie.getValue()+"]<br>");
        }

    }

  • 我们怎样是获取指定的cookie呢(有时候我们不需要全部是cookie,只需要特定的就可以了)
    但是我们发现cookie没有像getparamer()获取参数一样的方法(输出键将回去对应的值)。那我们就只有遍历整个cookie数组然后过滤特定的cookie了

  • 在项目中我们查询cookie的这个操作是很常用的,所以我们一般把将这个方法封装在一个工具类中**
  • cokieUtils工具类
package com.atguigu.utils;

import javax.servlet.http.Cookie;

//Cookie操作的工具类
public class CookieUtils {
    //查找特定名称的cookie对象
    public static Cookie findCookie(String name,Cookie[] cookies){
        if(name==null||cookies==null||cookies.length==0){
            return null;
        }
        for (Cookie cookie : cookies) {
            if(name.equals(cookie.getName())){
                return cookie;
            }
        }
        return null;
    }

}

cookie值的修改

  • 方案一:依据map集合的特性,存储进去一个相同key的map,将会更新集合中相同key的value

  • cookie的值的注意点:


谷歌和火狐浏览器如何查看cookie]


cookie的存活设置

  • 默认生命周期


当我们记录下网址,关闭浏览器然后再次打开后查看,刚刚存储的cookie真的消失了

  • 值为零,表示马上删除 Cookie
    首先需要确保浏览器中已经存在有了cookie
  • 已经存在的cookie
  • 点击删除后服务器发送给浏览器的http协议

    此时我们在浏览器中就 可以发现特定的cookie被删除了
  • 服务器中立即删除的方法
  • 指定cookie存活一段时间

  • 我们查看http协议的回复头:
  • servlet程序中的存活一段时间的方法

    此时当我们关闭浏览器后,重新打开发现我们的cookie值还在

Cookie的path属性

cookie的默认path是/工程名(工程路径)

我们是可以手动设置cookie的path的

  • CookieServlet中测试path的函数
 //测试cookie的有效path
    protected void testPath(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建一个cookie
        Cookie cookie = new Cookie("key6","Value6");
        //设置他的path
        //req.getContextPath()获取该请求的工程路径
        cookie.setPath(req.getContextPath()+"/abc");//path:/cookie/abc
        resp.addCookie(cookie);//将cookie和他的信息发送给客户端
    }
  • 当我们点击Cookie的路径设置后,会将我们创建号的cookie和path路径发送给浏览器:
    但是当我们在浏览器查看发送过来的cookie时。我却发现浏览器中并没有发现刚刚发送过来的cookie
  • 于是我们查看respose头

    原来这是谷歌为了保护隐私的一种做法。只有你的请求地址匹配的上当前cookie的path才能查看该cookie

cookie练习---面输入用户名登录

当我们第一次登录的时候,网站的用户名和密码是空的。当我们输入用户名和密码登录后,退出去再次登录时,我们的用户名已经自动帮我们填写了

  • 实现原理图
  • 这是登录页面login.jsp
<%--
  Created by IntelliJ IDEA.
  User: SWT
  Date: 2023/10/21
  Time: 20:12
  To change this template use File | Settings | File Templates.

--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="http://localhost:8080/cookie/">
    <title>Title</title>
    <form method="get" action="loginServlet">
      用户名:<input type="text" name="username" value="${cookie.username.value}" ><br>
        密码:<input type="password" name="password" ><br>
        登录<input type="submit" >

    </form>
</head>
<body>

</body>
</html>

  • 处理登录的LoginServlet
package com.atguigu.web;

import com.atguigu.utils.CookieUtils;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class LoginServlet extends BaseServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        login(req,resp);
    }

    protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        //再次访问时将username的值写入到login.jsp中(将会自动将有效的coookie发送给服务器)
        final Cookie username1 = CookieUtils.findCookie("username", req.getCookies());
        if(username1!=null){
            //这里可以不存储到域中,在jsp中直接可以获取到cookie
           // final ServletContext servletContext = req.getServletContext();
            //servletContext.setAttribute("username",username1.getValue());//将数据存储到域中
        }
        //获取用户名和密码
        final String username = req.getParameter("username");
        final String password = req.getParameter("password");
        if("swt".equals(username)&&"123456".equals(password)){
            resp.getWriter().write("成功登录成功");
            //并将username作为cookie对象发送给客户端保存
            Cookie cookie = new Cookie("username",username);
            cookie.setMaxAge(3600);//设置cookie的有效期
            resp.addCookie(cookie);//将cookie和他的信息发送给客户端保存
        }else {
            resp.getWriter().write("登录失败");
        }
    }
}

经过实验发现:当我们登录后,然后关闭浏览器打开再次登录,发现我们的用户名已经回显在了登录页面中
注意:我们也可以通过cookie保存到域中,然后在login.jsp中进行回显

  • 注意此时需要使用范围比较大的域,因为我们需要关闭浏览器,然后再次打开

Session(会话)

什么是Session会话

如何创建 Session 和获取(id 号,是否为新





注意:如果测试结果一直都是false,大概是浏览器有cookie缓存,打开浏览器设置清理一下就可以了

Session 域数据的存取

  • servlet中往session域中存放和取出数据的方法
//往session域中存储数据
    protected void setAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getSession().setAttribute("key","value");
        resp.getWriter().write("成功往session域中存储了数据");
    }
    //往session域中存放数据
    protected void getAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        final String value = (String) req.getSession().getAttribute("key");
        resp.getWriter().write("key的值为:" + value);
    }



对于req.getSession()方法没什么好纠结的。调用这个方法,如果没有session将会创建一个session对象,如果存在就返回这个sessin对象,都是返回session对象,对我们编程没什么影响

Sesssion超时的控制(生命周期的控制)

  • 和cookie一样,他的存活时间可以进行控制

  • Session的默认超时及配置

  • 默认市场的配置

    在 Tomcat 服务器的配置文件 web.xml中默认有以下的配置,它就表示配置了当前 Tomcat 服务器下所有的 Session
    超时配置默认时长为:30 分钟


    我们也可以在wab.xml中修改我们web工程的session时长(见文档),也可以修改个别session的超时时长

  • 修改个别session的超时时长(修改session3秒后超时)

  • servlet中设置超时时长为3秒的方法(值为正数设置超时时长)


    此时我们点击按钮将刚刚创建的session设置为3s超时销毁
    我们发现一个现象:
    1.当我们快速点击Session的创建和获取(id号、是否为新创建查看session是否有再次被创建,返回的一直是false(没有被创建,尽管,此时已经距离点击3秒销毁已经过了2秒)*
    2.我们在点击3秒销毁后,等待了3s后,再次点击,查看发现返回了true(sesion被重新创建)

  • 解释上面(session超时的介绍)

    当setMaxInactiveInterval(int time)方法设置为负数为,将超时时长设置为永不超时

浏览器和 Session 之间关联的技术内幕

疑问:以前讲过,session的范围是打开浏览器,然后关闭浏览器,session就没了。但是上面讲的是,session是由超时时长的,默认是30min,那为什么打开浏览器,然后关闭session就没有了呢?

当客户端访问服务器,服务器创建session对象的时候,会创建一个cookie对象。会将session对象的(key=jession value=session的id值)返回给客户端(通过响应头)
cookie的默认生命周期是一次sessin会话,而浏览器关闭则是一次会话结束,此时cookie消失

posted @ 2023-10-22 22:46  一往而深,  阅读(18)  评论(0编辑  收藏  举报