【JavaWeb】Cookie详解

会话技术

基本概念

指用户打开一个浏览器,访问一个网站,只要用户不关闭该浏览器,不管该用户点击多少个超链接,访问多少资源,直到用户关闭浏览器,整个这个过程我们称为一次会话。会话跟踪技术有Cookie和Session,Cookie技术是先出现的。一次会话中包含多次请求和响应。

功能

在一次会话内的多次请求间共享数据

分类

  • 客户端会话技术:Cookie
  • 服务器端会话技术:Session

Cookie技术

Cookie是客户端技术,程序把每个用户的数据以cookie的形式保存到各自浏览器中。当用户使用浏览器再次访问服务器中的web资源的时候,就会带着各自的数据过去。这样,web资源处理的就是用户各自的数据了。

快速入门

使用步骤:

1. 创建Cookie对象,绑定数据

new Cookie(String name, String value) 

2. 发送Cookie对象

response.addCookie(Cookie cookie) 

3. 获取Cookie,拿到数据

Cookie[] request.getCookies() 

案例:

在 CookieDemo1 中创建 Cookie 并发送,在 CookieDemo2 获取 Cookie

@WebServlet("/CookieDemo1")
public class CookieDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 创建 Cookie 对象,绑定数据
        Cookie cookie = new Cookie("msg","hello");
        // 发送 Cookie 对象
        response.addCookie(cookie);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
@WebServlet("/CookieDemo2")
public class CookieDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取 Cookie,拿到数据
        Cookie[] cookies = request.getCookies();
        // 遍历 cookies 数组,获取数据
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                String name = cookie.getName();
                String value = cookie.getValue();
                System.out.println(name + ":" + value);
            }
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

在同一个浏览器先访问CookieDemo1再访问CookieDemo2,CookieDemo2就会从Cookie中获取到msg中的hello。

Cookie 的实现原理

服务器中有两个资源:CookieDemo1和CookieDemo2,在 CookieDemo1 中创建 Cookie 并发送,在 CookieDemo2 获取 Cookie。底层是通过Http的 协议进行请求和响应,步骤如下:

  1. 客户端向服务器请求CookieDemo1的资源
  2. 服务器进行响应,响应头 set-cookie:msg=hello
  3. 客户端将响应头中的cookie值保存到客户端浏览器中
  4. 客户端向服务器请求CookieDemo2的资源,消息头 cookie:msg=hello
  5. 服务响应

Cookie 的细节

一次可以发送多个 Cookie

创建多个 Cookie 对象,使用 response 调用多次 addCookie 方法发送 Cookie 即可一次发送多个Cookie

@WebServlet("/CookieDemo3")
public class CookieDemo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 创建 Cookie 对象,绑定数据
        Cookie cookie1 = new Cookie("cookie1","hello");
        Cookie cookie2 = new Cookie("cookie2","zhangsan");
        // 发送 Cookie 对象
        response.addCookie(cookie1);
        response.addCookie(cookie2);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

 

Cookie 在浏览器中保存的时间 

默认情况下,当浏览器关闭后,Cookie 数据被销毁

设置持久化存储

    void setMaxAge(int seconds)
正数:将 Cookie 数据写到硬盘的文件中,并指定 Cookie 存活时间,时间到后,Cookie 文件将被自动删除。

负数:默认值

:删除 Cookie 信息

Cookie 能不能存储中文?

  1. 在 Tomcat 8 之前,Cookie 中不能直接存储中文数据。需要将中文数据进行转码,一般转为URL 编码。
  2. 在 Tomcat 8 之后,Cookie 支持中文数据。但特殊字符(如空格)还是不支持,建议使用 URL 编码存储,URL 解码解析。

Cookie 在不同项目下的共享

1. 假设在同一个 Tomcat 服务器中,部署了多个 Web 项目,默认情况下 Cookie 是不能共享的。

   设置 Cookie 的获取范围

  • void setPath(String path)
    • 默认情况下,设置当前的虚拟目录。所以一个项目中,所有 Cookie 共享
    • 如果要在不同项目中共享,则可以将path设置为 “/”

2. 假设在不同的 Tomcat 服务器中 Cookie想要共享,使用 setDomain(String path):如果设置一级域名相同,那么多个服务器之间 Cookie 可以共享

如:setDomain(".baidu.com"),那么 tieba.baidu.com 和 news.baidu.com 中 Cookie 可以共享

Cookie 的特点和作用

Cookie 的特点

  • Cookie 存储数据在客户端浏览器(数据不安全)
  • 浏览器对于单个 Cookie 的大小有限制(4kb)以及对同一个域名下的总 Cookie 数量也有限制(20个)(少量数据)

Cookie 的作用

  • Cookie 一般用于存储少量的不太敏感的数据
  • 可以在不登录的情况下,完成服务器对客户端的身份识别

案例-记住上一次访问时间

需求

    1. 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问。
    2. 如果不是第一次访问,则提示:欢迎回来,您上次访问时间为:显示时间字符串

需求分析

1. 可以采用Cookie来完成

2. 在服务器中的Servlet判断是否有一个名为lastTime的cookie                                                                                                                   如果有:不是第一次访问
                    1. 响应数据:欢迎回来,您上次访问时间为:2018年6月10日11:50:20
                    2. 写回Cookie:lastTime=2018年6月10日11:50:01
         如果没有:是第一次访问
                    1. 响应数据:您好,欢迎您首次访问
                    2. 写回Cookie:lastTime=2018年6月10日11:50:01 

程序认真看,特别是注释:

package cn.lwl.web.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;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author liwenlong
 * @data 2020/3/24
 */
@WebServlet("/CookieServletDemo")
public class CookieServletDemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应的消息体的数据格式以及编码
        response.setContentType("text/html;charset=utf-8");

        //获取所有cookie
        Cookie[] cookies = request.getCookies();
        //遍历cookie数组
        if (cookies != null && cookies.length > 0) {
            for (Cookie cookie : cookies) {
                //获取cookie的名称
                String cookieName = cookie.getName();
                if (cookieName.equals("lastTime")) { //不是第一次访问

                    //响应数据
                    String value = cookie.getValue(); //获取上次访问的时间
                    //URL解码
                    value = URLDecoder.decode(value, "utf-8");
                    //向网页上写字符串
                    response.getWriter().write("<h1>欢迎回来,您上次的访问时间是" + value);

                    //获取当前时间的字符串,重新设置为cookie的值,重新发送cookie
                    Date date = new Date();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
                    String str_date = sdf.format(date);
                    //上面的空格tomcat是无法解析的,需要使用URL编码解码
                    //URL编码
                    str_date = URLEncoder.encode(str_date, "utf-8");
                    cookie.setValue(str_date);
                    //设置cookie存活时间
                    cookie.setMaxAge(60 * 60 * 24 * 30 * 12);//一年
                    response.addCookie(cookie);

                    break;
                }
            }
        }

        if (cookies == null || cookies.length == 0 ) {//第一次访问

            //获取当前时间的字符串,重新设置为cookie的值,重新发送cookie
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
            String str_date = sdf.format(date);
            str_date = URLEncoder.encode(str_date, "utf-8");
            Cookie cookie = new Cookie("lastTime", str_date);
            cookie.setValue(str_date);
            //设置cookie存活时间
            cookie.setMaxAge(60 * 60 * 24 * 30 * 12);//一年
            response.addCookie(cookie);
            //向网页上写字符串
            response.getWriter().write("<h1>欢迎您第一次访问");

        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

 

发布了173 篇原创文章 · 获赞 120 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/zzu_seu/article/details/105059496
今日推荐