Cookie详解(Java)

Cookie详解

一、Cookie简介

1.1 什么是Cookie

Cookie是服务器通知客户端保存键值对的一种技术。当客户端有Cookie后,每次请求都发送给服务器。
注:
1、每个Cookie的大小不能超过4kb;
2、Cookie的值不应该包含空格、方括号[ ]、圆括号()、等号=、逗号,、双引号“”、斜杠\、问号?、@符号、冒号:和分号;。空值在所有浏览器上的行为也不一定相同。
3、如果一定要的话,就得用Base64编码

在这里插入图片描述

1.2 Java如何创建Cookie

直接代码送上:
首先是我们的BaseServlet.java文件

package com.hstc.edu;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决post请求中文乱码问题
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html; charset=UTF-8");

        String action = req.getParameter("action");
        try {
            // 获取action业务鉴别字符串,获取相应的业务 方法反射对象
            Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
            // 调用目标业务方法
            method.invoke(this, req, resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

然后是我们的CookieServlet.java文件:

package com.hstc.edu;

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{
        System.out.println("我被调用了!!");
        //1、创建Servlet对象
        Cookie cookie = new Cookie("key1","value1");
        //2、通知客户端保存Cookie
        resp.addCookie(cookie);

        resp.getWriter().write("Cookie创建成功");
    }
}

然后我们在web.xml中注册我们的Servlet:

<?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>CookieServlet</servlet-name>
        <servlet-class>com.hstc.edu.CookieServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CookieServlet</servlet-name>
        <url-pattern>/cookieServlet</url-pattern>
    </servlet-mapping>
</web-app>

最后编写我们的脚本文件(HTML):

<!DOCTYPE html>
<html lang="ch">
<head>
    <meta charset="UTF-8">
    <title>Cookie学习实例</title>
    <!--
    	这里的base指的是本网页基于的路径,跟下面可以直接用cookieServlet有直接关系
		说直白点就是下面所有的路径都将会在最前面加上这个路径
	-->
    <base href="http://localhost:8080/Cookie/">
    <style type="text/css">
        iframe{
            position: absolute;
            left: 500px;
            top: 0px;
        }

        ul li{
            width: 300px;
            list-style: none;
        }
    </style>
</head>
<body>
    <div>
        <ul>
            <li>
                <a href="cookieServlet?action=createCookie" target="target">Cookie的创建</a>
            </li>
            <li>
                <a href="cookieServlet?action=" target="target">Cookie的获取</a>
            </li>
            <li>
                <a href="cookieServlet?action=" target="target">修改Cookie值</a>
            </li>
            <li>Cookie的生命周期</li>
            <li>
                <ul>
                    <li>
                        <a href="cookieServlet?action=" target="target">Cookie的默认存活时长(会话)</a>
                    </li>
                    <li>
                        <a href="cookieServlet?action=" target="target">立刻删除Cookie</a>
                    </li>
                    <li>
                        <a href="cookieServlet?action=" target="target">让Cookie存活3600s(1小时)</a>
                    </li>
                </ul>
            </li>
            <li>
                <a href="cookieServlet?action=" target="target">Cookie的路径设置</a>
            </li>
            <li>
                <a href="cookieServlet?action=" target="target">Cookie的用户免登陆练习</a>
            </li>
        </ul>
    </div>
    <iframe name="target" width="500" height="500"></iframe>
</body>
</html>

运行结果:
点击了Cookie的创建后:
在这里插入图片描述
Cookie创建的图文说明:
在这里插入图片描述
注意:Cookie可以同时创建多个。代码也很简单,请看:

package com.hstc.edu;

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、创建Servlet对象
        Cookie cookie = new Cookie("key1","value1");
        //2、通知客户端保存Cookie
        resp.addCookie(cookie);
        //同时创建并保存多个cookie
        Cookie cookie2 = new Cookie("key2","value2");
        Cookie cookie3 = new Cookie("key3","value3");
        resp.addCookie(cookie2);
        resp.addCookie(cookie3);
        resp.getWriter().write("Cookie创建成功");
    }
}

1.3 获取Cookie的name和value

在上面基础上,在CookieServlet.java类中编写函数:

    protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        Cookie[] cookies = req.getCookies();
        for(Cookie cookie : cookies){
            resp.getWriter().write(cookie.getName()+": "+cookie.getValue()+"<br/>");
        }
    }

然后再html中做个引导:
在这里插入图片描述
然后运行服务器,点击Cookie的获取即可在iframe标签中显示当前所有的Cookie的信息。
在这里插入图片描述

1.4 寻找是否有特定Cookie

    protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        Cookie myCookie = null;
        Cookie[] cookies = req.getCookies();
        for(Cookie cookie : cookies){
            //使用你想获取的cookie的键去配对是否有你想要的cookie
            if ("key2".equals(cookie.getName())){
                //找到了,给myCookie赋值
                myCookie = cookie;
                //doSomething
                System.out.println("小样,被我抓到了吧");
                //找到了就break跳出for循环,不要乱费时间,这是好习惯
                break;
            }
        }
        //找不到怎么办
        if(myCookie == null){
            //doSomething
            System.out.println("我找不到呀!!!");
        }
    }

鉴于这个方法比较常用,我们也可以把他封装成一个函数,放在utils包中,供我们日常使用:

package com.hstc.utils;

import javax.servlet.http.Cookie;

public class CookieUtils {
    public static Cookie findCookie(String name,Cookie[] cookies){
        //输出的参数不对劲,不给干活
        if(name == null || cookies.length == 0 || cookies == null){
            return null;
        }
        //找到了就返回cookie对象
        for (Cookie cookie: cookies){
            //查找有没有想要的Cookie
            if (name.equals(cookie.getName())){
                return cookie;
            }
        }
        //找不到返回null值
        return null;
    }
}

使用的话只需要:

    protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        Cookie myCookie = CookieUtils.findCookie("key2",req.getCookies());
        if (myCookie != null){
            //找到了,doSomething
            System.out.println("我找到啦!!!");
        }else {
            //找不到,doSomething
            System.out.println("骗谁呢你!!!");
        }
    }

1.5 Cookie值的修改

方案一(直接写新的盖上去)

步骤如下:
1、创建一个同名的Cookie对象
2、在构造器中,赋予Cookie值
3、调用response.addCookie(cookie)方法

    protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        Cookie cookie = new Cookie("key1","newValue1");
        resp.addCookie(cookie);

        resp.getWriter().write("成功修改name为key1的Cookie值");
    }
方案二(找到要改的,再用Cookie对象的方法改)

步骤:
1、查找要修改的Cookie对象
2、用cookie对象的setValue方法赋予新的值
3、用response的addCookie修改客户端的值

    protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//        Cookie cookie = new Cookie("key1","newValue1");
//        resp.addCookie(cookie);
        Cookie myCookie = CookieUtils.findCookie("key2",req.getCookies());
        if (myCookie != null){
            myCookie.setValue("NewValue2");
            resp.addCookie(myCookie);
        }
        resp.getWriter().write("成功修改name为key2的Cookie值");
    }

1.6 Cookie的生命控制

使用setMaxAge(int expiry)方法即可。

  • 当expiry为正数n,表示存活n秒
  • 当expiry为负数m,表示退出浏览器就消失(默认情况)
  • 当expiry为0,表示马上删除Cookie
    //默认情况,可以看Cookie类的代码,他是开源的
    protected void defaultLife(HttpServletRequest req, HttpServletResponse resp){
        Cookie cookie = new Cookie("life","defaultLife");
        cookie.setMaxAge(-1);
        resp.addCookie(cookie);
    }

    //等于0,让他马上消失
    protected void deleteLife(HttpServletRequest req, HttpServletResponse resp){
        Cookie cookie = new Cookie("delete","deleteLife");
        cookie.setMaxAge(0);
        resp.addCookie(cookie);
    }

    //等于正数,存活3600s,也就是一小时
    protected void oneHourLife(HttpServletRequest request, HttpServletResponse response){
        Cookie cookie = new Cookie("hour","hour");
        cookie.setMaxAge(3600);
        response.addCookie(cookie);
    }

Cookie类的源码:
在这里插入图片描述

1.7 Cookie修改path属性

在这里插入图片描述
这个path有什么用呢?
作用:可以用来过滤哪些Cookie可以发送给服务器,哪些不发。
举个例子:
现在有CookieA和CookieB的path属性分别如下:
CookieA —— path = /Cookie
CookieB —— path=/Cookie/hello

现在,我们如果访问地址:
http:localhost:8080/Cookie/cookie.html
那么CookieA 会发送给服务器,CookieB则不会

如果我们访问的地址是:
http:localhost:8080/Cookie/hello/cookie.html
那么,此时CookieA和CookieB都会发送给服务器

那么,怎么设置path路径呢,很简单,只需要用Cookie对象的setPath()方法即可。演示代码来一波:

    protected void updatePath(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        Cookie cookie = new Cookie("path","path1");
        //request的getContextPath()方法用来获取工程路径
        cookie.setPath(req.getContextPath() + "/hello");
        resp.addCookie(cookie);
        resp.getWriter().write("成功添加了path = 工程路径/path 的Cookie");
    }

当点击Cookie的路径设置的时候,iframe标签成功显示成功添加了path = 工程路径/path 的Cookie,但是我们刷新Application的Cookie却发现,没有出来新的Cookie。
这是因为我们当前的路径是http://localhost:8080/Cookie/cookie.html,服务器不接收路径为http://localhost:8080/Cookie/hello的Cookie。

为了证明我没有动手脚,特地再截图一张Network下的图片,可以看到响应头的Set-Cookie里面是有设置path = path的。
在这里插入图片描述
此时,我们再访问路径http://localhost:8080/Cookie/hello/cookie.html,可以看到cookie值被放到了这里。
不仅如此,我们Path为/Cookie以及/的Cookie也全都可以看到。
在这里插入图片描述

1.8 Cookie实战——免用户名登录

实现过程:
在这里插入图片描述
代码走一波:
显示网页login.jsp文件的源码:
不会EL表达式的,点击此处,我已经准备了EL表达式的详细笔记。

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

然后是我们的Servlet程序,LoginServlet.java源码:

package com.hstc.edu;

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;

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        //登录成功保存Cookie
        if(username.equals("Keeling") && password.equals("123456")){
            Cookie cookie = new Cookie("username",username);
            //Cookie保存一周
            cookie.setMaxAge(3600 * 24 * 7);
            resp.addCookie(cookie);
            System.out.println("登录成功");
        }else {
            System.out.println("登录失败");
        }
    }
}

然后我们在web.xml进行注册:

    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.hstc.edu.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值