javaWeb ---cookie使用(详尽,从0-1)

本文详细介绍了Cookie的原理、组成部分、属性设置以及在JavaWeb中的应用。通过示例展示了如何配置和使用Cookie,强调了HttpOnly属性对于防止XSS攻击的重要性,并分享了在实现过程中遇到的问题和解决思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Cookie是什么?

  • 类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息。
  • 原理: 一个 Web 站点可能会为每一个访问者产生一个唯一的ID, 然后以 Cookie 文件的形式保存在每个用户的机器上。如果使用浏览器访问 Web, 会看到所有保存在硬盘上的 Cookie。在这个文件夹里每一个文件都是一个由“名/值”对组成的文本文件,另外还有一个文件保存有所有对应的 Web 站点的信息。在这里的每个 Cookie 文件都是一个简单而又普通的文本文件。透过文件名, 就可以看到是哪个 Web 站点在机器上放置了Cookie(当然站点信息在文件里也有保存)
    在这里插入图片描述cookies组成部分

Cookie是一段不超过4KB的小型文本数据,由一个名称(Name)、一个值(Value)
Expires属性:设置Cookie的生存期
Path属性:定义了Web站点上可以访问该Cookie的目录
Domain属性:指定了可以访问该 Cookie 的 Web 站点或域
Secure属性:指定是否使用HTTPS安全协议发送Cookie
HTTPOnly 属性 :用于防止客户端脚本通过document.cookie属性访问Cookie,

验证使用方法:
  • 导入Httpservlet-api包
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

配置:

  1. 结构:
    在这里插入图片描述tomcat 配置
    在这里插入图片描述web.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    
    <servlet>
        <servlet-name>cookies</servlet-name>
        <servlet-class>cookies.CookiesTest01</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>cookies</servlet-name>
        <url-pattern>/cookies</url-pattern>
    </servlet-mapping>
</web-app>

ok!确保能够tomcat 能够跑起来之后,就进行正式的环节:

编写程序

cookie是由名称、内容、作用路径、作用域、协议、生存周期组成----见名知意
Cookies 方法如下:
在这里插入图片描述
此处使用doGet方法,doPost效果一样,只是请求方式和请求数据的大小限制问题、安全问题等不同,读者可以查阅相关资料。

package cookies;
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 javax.xml.crypto.Data;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

public class CookiesTest01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 处理字符乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        // 设置访问形式
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();  //返回前端写出
        // 获取浏览器传输的cookies
        Cookie[] cookies = req.getCookies();
        System.out.println("获取的cookie"+cookies);
        // 判断用户是否是第一次得到cookies
        if (cookies!=null){
            out.write("上次访问的信息是:");
            for (int i=0;i<cookies.length;i++) {
                Cookie cookie = cookies[i];
//                System.out.println("_______不为空的cookies 为_______:"+cookie.getName().toString());
                if (cookie.getName().equals("lastAccessTime")) {
                    long lastAccessTime = Long.parseLong(cookie.getValue());   //获取cookies的值
//                    System.out.println(lastAccessTime);
                    System.out.println(cookie.isHttpOnly());
                    Date date = new Date(lastAccessTime);
//                    System.out.println(date);
                    out.write(date.toLocaleString() + " cookies 美妙!!  ");
                    System.out.println(date.toLocaleString());
                }
            }
        }else {
            out.write("这是您第一次访问本站\n");
        }
        //用户访问过之后重新设置用户的访问时间,存储到cookie中,然后发送到客户端浏览器

        Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");  //System.currentTimeMillis()+"" 《-中间不能加其他字符
        resp.addCookie(cookie);
        out.write("This is addCookies Address: "+String.valueOf(cookie));

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}

第一次成功访问在这里插入图片描述
当存在cookies时会进入for循环,寻找上次的cookie时间
在这里插入图片描述
cookies 作用时间设置

 Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");  //System.currentTimeMillis()+"" 《-中间不能加其他字符
        //设置Cookie的有效期为1天
        cookie.setMaxAge(24*60*60);
        resp.addCookie(cookie);

在这里插入图片描述cookies设置:

HttpOnly属性,HttpOnly属性很重要,如果您在cookie中设置了HttpOnly属性,那么通过js脚本(document.cookie)将无法读取到cookie信息,这样能一定程度上的防止XSS攻击

 Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");  //System.currentTimeMillis()+"" 《-中间不能加其他字符
        //设置Cookie的有效期为1天
        cookie.setMaxAge(24*60*60);
        cookie.setHttpOnly(true);
        resp.addCookie(cookie);

在这里插入图片描述方法介绍到此结束,如果在过程中有什么问题,可以查阅资料或者留言

=========================================

cookies底层是怎么实现的了?一直很头疼,于是就开了底层的方法:
当获取cookie的值后,比较 isToken和name 是否为空,抛出异常,给name 和value 赋值

public Cookie(String name, String value) {
        if (name == null || name.length() == 0) {
            throw new IllegalArgumentException(
                    lStrings.getString("err.cookie_name_blank"));
        }
        if (!isToken(name) ||
                name.equalsIgnoreCase("Comment") || // rfc2019
                name.equalsIgnoreCase("Discard") || // 2019++
                name.equalsIgnoreCase("Domain") ||
                name.equalsIgnoreCase("Expires") || // (old cookies)
                name.equalsIgnoreCase("Max-Age") || // rfc2019
                name.equalsIgnoreCase("Path") ||
                name.equalsIgnoreCase("Secure") ||
                name.equalsIgnoreCase("Version") ||
                name.startsWith("$")) {
            String errMsg = lStrings.getString("err.cookie_name_is_token");
            Object[] errArgs = new Object[1];
            errArgs[0] = name;
            errMsg = MessageFormat.format(errMsg, errArgs);
            throw new IllegalArgumentException(errMsg);
        }

        this.name = name;
        this.value = value;
    }

一步步下去之后,还是回到了Httpservlet,感觉就是高耦合,一步步联系,各个类相互使用,有兴趣的同学可以看看23重设计模式

在这里插入图片描述

下面本人在这过程中遇到的一些问题及解决思路:有兴趣的读者可以批评指导:
第一次写实现类的时候因为System.currentTimeMillis()没有加任何东西报错,也没有任何提示性错误,所以自作主张的加上了System.currentTimeMillis()+“1345”
在这里插入图片描述运行之后竟然不能输出到页面???

纳闷的我,就在debug之路上越走越远。
        Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"12313");  //System.currentTimeMillis()+"" 《-中间不能加其他字符
        //设置Cookie的有效期为1天
        cookie.setMaxAge(24*60*60);
        cookie.setHttpOnly(true);
        resp.addCookie(cookie);
        out.write("This is addCookies Address: "+String.valueOf(cookie));
  • [1 ] 查看cookie设置的name并没有添加在cookie上
    在这里插入图片描述 默默的查看request信息,ok,没毛病,是读取进来的,老铁。
    在这里插入图片描述 再查看cookie的值,是请求进来的,硬着头皮看下去,坚强
    在这里插入图片描述 最后辗转反侧,终于发现了,是有一个无效值,程序根本没有执行到
    Cookie cookie = new Cookie(“lastAccessTime”, System.currentTimeMillis()+“12313”);
    真相清晰了,就是这语句有问题,查阅资料之后发现这个中间不能有值,我当时是想检验是否成功,傻里傻气的加上,导致了这个debug
 Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");  //System.currentTimeMillis()+"" 《-中间不能加其他字符
package cookies;

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 javax.xml.crypto.Data;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

public class CookiesTest01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 处理字符乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        // 设置访问形式
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();  //返回前端写出
        // 获取浏览器传输的cookies
        Cookie[] cookies = req.getCookies();
        System.out.println(cookies);
        // 判断用户是否是第一次得到cookies
        if (cookies!=null){
            out.write("上次访问的信息是:");
            for (int i=0;i<cookies.length;i++){
                Cookie cookie = cookies[i];
                System.out.println("不为空的cookies 为:=="+cookie.getName());
                if (cookie.getName().equals("lastAccessTime")){
                    long lastAccessTime = Long.parseLong(cookie.getValue());   //获取cookies的值
                    System.out.println(lastAccessTime);
                    Date date = new Date(lastAccessTime);
                    System.out.println(date);
                    out.write(date.toLocaleString());
                }
            }
        }else {
            out.write("这是您第一次访问本站");
        }
        //用户访问过之后重新设置用户的访问时间,存储到cookie中,然后发送到客户端浏览器
        Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"123 ");
        System.out.println("添加的cookie:"+cookie.getName());
        resp.addCookie(cookie);
        out.write("这是返回设置的cookies时间"+cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}

                                                  O了,希望这篇文章能够帮助到您!@_^_@
                                                  觉得不错的话,欢迎点赞关注♥♥♥
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值