Java Web中的Cookie技术 (小甜心) + 分析原理 + 概念回顾 + 保存上次登录时间(实时更新)

目录

关于Cookie相关的概念:(Cookie的原理在下面哦)

一. Cookie可以用来干嘛

二. Cookie的生命周期

三. Cookie的有效路径

四.Cookie的注意事项:

五.Cookie的原理及其原理图

六.案例分析

一. 保存上次用户登录的时间


Cookie和Session是会话技术的核心,在B/S架构中,我们的浏览器和服务器进行交互的过程中,会产生一些交互的数据,比如用户名密码等,因为HTTP协议是无记忆性的,所以为了保存这些交互的数据产生了Cookie和Session技术,其中Cookie信息是保存在浏览器中,Session信息则保存在服务器中。


关于Cookie相关的概念:(Cookie的原理在下面哦)

一. Cookie可以用来干嘛

  1. Cookie可以用来保存上次访问的时间。 (以下有案例)
  2. Cookie可以用来保存登录用户名和密码,免于下次再登录 (以下有案例)
  3. 网站的个性化,定制网站的服务等。

二. Cookie的生命周期

当服务器中 response.addCookie(Cookie)时,浏览器就会通过HTTP响应接受到来自服务器的Cookie信息并保存在浏览器中。

Cookie的生命周期是从创建开始计时,当浏览器关闭,当前浏览器的Cookie依旧在计时(和后续文章中的Session生命周期有不同)。当生命时间结束,就会被浏览器销毁

cookie.setMaxAge()是用来设置Cookie的生命周期的。

正数:是该Cookie能存活的秒数。

负数:是浏览器一关闭就删除该Cookie默认值就是-1

0:立马删除该Cookie。

以下进行Cookie的抓包分析:

写一个代码,添加一个Cookie的信息,用户名给浏览器并设置生命周期是20s

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.URLEncoder;
/**
 * @author ygd
 */
@WebServlet("/cl")
public class CookieLive extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        //大部分的浏览器的字符集是ISO-8859-1不支持中文,对中文进行URL编码发送给浏览器
        String name = URLEncoder.encode("小明");
        Cookie cookie = new Cookie("username", name);
        cookie.setMaxAge(20);
        //发送Cookie信息给浏览器
        resp.addCookie(cookie);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

抓包分析:

由Set-Cookie:中username=xxx的一部分就是传入的Cookie信息,Max-Age=20,是设置的生命周期为20s。 后面的一堆是这个Cookie被创建的时间,和北京时间相差八个小时,这是因为设置的时区不同导致的。

20s之内当我们访问我们自己的网站的时候,浏览器就会将浏览器端所保存的Cookie信息通过HTTP请求,发送给我们的服务器,存在于请求头中的Cookie中

20s过后当浏览器向我们的网站再次发出HTTP请求的时候,就不会将我们设置的Cookie信息携带发送给服务器,Cookie超过生命周期20s被销毁了。这里的Cookie中的JSession是Session技术(后面进行讲解)

三. Cookie的有效路径

Cookie的有效路径决定浏览器访问服务端的时候将哪些Cooke信息通过HTTP请求发送给服务端。

Cookie.setPath()是来设置Cookie的有效路径的。

当HTTP请求的URL包含设置的有效路径,浏览器才会将Cookie信息发送给服务器

比如:

cookie1.setPath = /工程路径

cookie2.setPath = /工程路径/aaa

请求地址: http://ip:端口/工程路径/资源

cookie1 会发给服务器

cookie2 不会发给服务器

请求地址: http://ip:端口/工程路径/aaa/资源

cookie1 会发给服务器

cookie2 会发给服务器

进行代码分析:

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;
/**
 * @author 酸奶
 */
@WebServlet("/d1")
public class demo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie cookie1 = new Cookie("u1", "a");
        cookie1.setPath("/web_demo6");
        Cookie cookie2 = new Cookie("u2", "b");
        cookie2.setPath("/web_demo6/aa");
        Cookie cookie3 = new Cookie("u3", "c");
        cookie3.setPath("/web_demo6/aa/bb");
        resp.addCookie(cookie1);
        resp.addCookie(cookie2);
        resp.addCookie(cookie3);
    }
    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

抓包分析:

访问此网站资源时,对浏览器进行抓包,当服务器addCooke()时,服务端会创建Set-Cookie的响应头通过HTTP响应发送给浏览器,每个Cookie信息都会被浏览器保存如图:

当访问的资源为/web_demo6/aa/bb时全部的Cookie信息都会发送给服务器:

当访问的资源为/web_demo6/aa时只有u1,u2的Cookie信息都会发送给服务器:

当访问的资源为/web_demo6时只有u1的Cookie信息都会发送给服务器:

四.Cookie的注意事项:

  1. Cookie是保存在浏览器中的。
  2. 服务器可以发送多个Cookie给客户端,浏览器可以保存多个Cookie
  3. 浏览器保存Cookie的大小是有限制的大概一般是在4KB左右
  4. Cookie建议不存中文一般的浏览器和web服务器用ISO-8859-1进行解码(不支持中文),但是可以用URL编码和解码解决Cookie的中文乱码问题。

五.Cookie的原理及其原理图

当服务器端创建Cookie对象并调用addCookie()的方法的时候,服务端就会在HTTP响应头中生成一个Set-Cookie:k1 = v1的响应头,并通过HTTP响应发送给浏览器,浏览器接收到HTTP响应对Set-Cookie:k1 = v1进行解析,并将Cooie信息保存到本地浏览器中,当再次访问服务器的时候浏览器的请求头中就会携带Cookie:k1 = v1发送给服务端,供给服务端进行相应的业务处理。

六.案例分析

一. 保存上次用户登录的时间

import javax.servlet.ServletException;
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.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * @author 酸奶
 * 思路:当http请求后获取cookie如果有最后一次访问的属性,则响应给客户端
 * 没有则自己进行设置
 */
@WebServlet("/demo01")
public class Demo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("来一次请求");
        Cookie[] cookies = req.getCookies();
        //解决输出中文乱码问题
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        boolean flag = false;
        if(cookies.length > 0 && cookies != null) {
            for (Cookie cookie : cookies) {
                String name = cookie.getName();
                if ("LastName".equals(name)) {
                    flag = true;
                    String value = cookie.getValue();
                    String de_value = URLDecoder.decode(value, StandardCharsets.UTF_8);
                    writer.println("该网站上次访问的时间是:" + de_value);
                    //重新设置现在的时间
                    Date date = new Date();
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                    String format = simpleDateFormat.format(date);
                    String encode = URLEncoder.encode(format, StandardCharsets.UTF_8);
                    cookie.setValue(encode);
                    resp.addCookie(cookie);
                }
            }
        }
        if(cookies.length == 0 || cookies == null || flag == false)
        {
            Date date = new Date();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            String format = simpleDateFormat.format(date);
            String encode = URLEncoder.encode(format, StandardCharsets.UTF_8);
            Cookie cookie = new Cookie("LastName",encode);
            resp.addCookie(cookie);
            writer.println("欢迎你首次访问~");
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

结果显示:1

2.