Cookie与Session(会话技术)

会话技术

  • 会话:一次会话当中包含了多次的请求和响应
  • 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
  • 会话的功能:在一次会话的范围之内的多次请求之间,共享数据
  • 共享数据的方式:客户端会话技术(cookie),服务器端会话技术(session

Cookie

  • 概念:客户端会话技术,将数据保存到客户端

Cookie快速入门

  • 创建Cookie对象,绑定数据:Cookie(String name,, String value)
  • 发送Cookie对象:response.addCookie(Cookie cookie)
  • 获取Cookie,拿到数据:Cookie[] request.getCookies()
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //1.创建cookie对象
    Cookie cookie = new Cookie("msg", "hello");
    //2.response发送cookie
    response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //3.获取Cookie
    Cookie[] cookies = request.getCookies();
    //4.获取数据
    if (cookies != null) {
        for (int i = 0; i < cookies.length; i++) {
            System.out.println(cookies[i].getName() + " : " + cookies[i].getValue());
        }
    }
}

Cookie的实现原理

  • 图解
    在这里插入图片描述
    客户端浏览器第一次向服务器发送请求,服务器会做出响应,也就是服务器会将Cookie对象发送给客户端浏览器,其发送方式就是在响应头set-cookie当中设置cookienamevalue,浏览器收到cookie对象就会保存。
    当客户端浏览器第二次发送请求的时候,就会自动的将cookie发送给服务器,其发送方式就是在请求头cookie当中设置cookienamevalue,服务器端就可以通过request对象当中的方法获取cookie对象。
  • 浏览器抓包
    在这里插入图片描述
    在这里插入图片描述

Cookie细节处理

  • 一次可不可以发送多个Cookie
    可以通过创建多个Cookie对象和多次调用addCookie方法即可实现,一次性发送多个Cookie对象
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //1.创建cookie对象
    Cookie cookie = new Cookie("msg", "hello");
    Cookie cookie1 = new Cookie("msg", "world");
    //2.response发送cookie
    response.addCookie(cookie);
    response.addCookie(cookie1);
}

在这里插入图片描述

  • cookie在浏览器当中能保存多长时间
    默认情况下,当浏览器被关闭之后,Cookie数据被销毁
    但是我们可以通过设置Cookie对象的生命周期来实现Cookie对象的持久化存储,可以使用cookie.setMaxAge(int seconds)来设置生命周期
    seconds>0:将cookie数据写到硬盘当中,持久化存储。seconds表示cookie存活的时间为seconds秒
    seconds<0:默认值
    seconds=0:删除cookie值
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Cookie cookie = new Cookie("msg", "hello");
    cookie.setMaxAge(600);
    response.addCookie(cookie);
}
  • cookie能否发送中文
    在tomcat8版本之前,cookie中不能直接存储中文数据,需要将中文数据进行转码,采用URL编码(%E3)
    在tomcat8版本及其之后版本,cookie中都支持中文数据
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Cookie cookie = new Cookie("msg", "你好");
    response.addCookie(cookie);
}

在这里插入图片描述

  • cookie获取范围多大
    假设在一个tomcat当中部署多个web项目,那么在这些web项目当中的cookie能不能共享?
    实际上,在默认情况下,cookie是不能共享的,但是我们可以通过cokkie.setPat(String path)方法来设置cookie的获取范围,其中path是web项目的虚拟路径
  • 不同服务器之间cookie共享的问题
    可以使用cookie.setDomain(STring path),将path设置为相同的一级域名,那么多个服务器就可以实现cookie之间的共享。
    例如,setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中的cookie就可实现共享

cookie的特点和作用

  • cookie的数据存储在客户端浏览器
  • 浏览器对于单个的cookie的大小有限制(4kb左右),以及对于同一个域名下的cookie的数目也有限制(20个以内)。
  • 作用:一般存储不太敏感的少量数据,能够在不登录的情况下,完成服务器对客户端的身份识别

cookie案例:记住上一次的访问时间

  • 需求:访问一个servlet,如果是第一次访问,则提示:您好欢迎首次访问;如果不是第一次访问,则提示:欢迎回来,您上次访问的时间为:显示时间字符
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;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.Date;

@WebServlet(urlPatterns = {"/CookieDemo"})
public class CookieDemo extends HttpServlet {
    private int cookieContains(Cookie[] cookies) {
        if (cookies == null) {
            return -1;
        }
        for (int i = 0; i < cookies.length; i++) {
            if (cookies[i].getName().equals("time")) {
                return i;
            }
        }

        return -1;
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        Cookie[] cookies = request.getCookies();
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = URLEncoder.encode(simpleDateFormat.format(date), "utf-8");

        int count = cookieContains(cookies);
        if (count == -1) {
            response.getWriter().write("欢迎首次访问");
            Cookie cookie = new Cookie("time", time);
            response.addCookie(cookie);
        } else {
            response.getWriter().write("欢迎回来,上次访问时间为:" + URLDecoder.decode(cookies[count].getValue(), "utf-8"));
            cookies[count].setValue(time);
            response.addCookie(cookies[count]);
        }


    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
  • 注意:cookie对象专递数据时,应该注意数据编码格式,使用URLEncoder对象进行URL编码

Session

  • 概念:服务器端会话技术,再一次绘画的多次请求之间共享数据,将数据保存在服务器端的对象(HttpSession)当中。
  • 获取HttpSession对象:HttpSession session = request.getSession();
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    HttpSession session = request.getSession();
    session.setAttribute("msg", "HELLO WORLD!");
    System.out.println(session.getAttribute("msg"));
    session.removeAttribute("msg");
}

Session的原理

  • 图解
    在这里插入图片描述
    实际上Session是依赖于Cookie来实现的,在第一次创建session对象的时候,会分配相应的id,通过cookie来发送给客户端浏览器,在客户端浏览器进行请求时,将会发送id给服务器,服务器就会按照id获取唯一的session对象
  • 浏览器抓包
    在这里插入图片描述
    在这里插入图片描述

Session的细节

  • 当客户端关闭之后服务器不关闭,两次获取session是同一个吗?
    默认情况下,两次获取的session并不是同一个。
    如果我们期望客户端关闭之后获取的仍然相同,我们可以使用cookie来完成。实际上就是设置JSESSIONID的请求头
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    HttpSession session = request.getSession();

    Cookie cookie = new Cookie("JSESSIONID", session.getId());
    cookie.setMaxAge(60 * 60);
    response.addCookie(cookie);

    System.out.println(session);
}
  • 客户端不关闭,服务器端关闭之后,两次获取的session是同一个吗?
    不是同一个,但是在某些情况下我们需要保证数据的不丢失,因此我们需要将session进行钝化(序列化)和活化(反序列化),以此来保证我们的session对象在服务器关闭之后数据也不会丢失,实际上tomcat可以帮我们完成钝化和活化操作。
  • session默认的失效时间(session什么时候会被销毁)
    session.invalidate()方法的调用可以销毁session对象;
    session对象的默认存活时间是30分钟,可以通过tomcat的web.xml来配置session的默认存活时间;

session的特点

  • session用于存储一次会话的多次请求之间的数据,存储在服务器端
  • session可以用于存储任意类型、任意大小的数据

session与cookie的区别

  • session存储在服务器端,cookie存储在浏览器端
  • session没有数据大小的限制,而cookie存在数据大小的限制
  • session数据相对安全,cookie的数据相对不安全
发布了96 篇原创文章 · 获赞 19 · 访问量 4332

猜你喜欢

转载自blog.csdn.net/qq_43446165/article/details/104325084