Cookie

资料和记录来自多年前 B 站的学习

Cookie

1、Cookie是由服务器通知客户端保存键值对的一种技术。

2、每组键值对大小不能超过4kb。

3、当客户端保存了cookie(键值对)之后,每次请求都会把cookie发送给服务器。

4、Cookie的键和值不能直接的支持中文(空格、方括号、圆括号、等号、逗号、双引号、斜杠、问号、at 符号、冒号和分号。空值在所有浏览器上的行为不一定相同)

如何创建Cookie

  1. 在服务器代码中 new 一个 Cookie 对象

调用response.addCookie( cookie对象 );

protected void createCookie(HttpServletRequest request,
             HttpServletResponse response) throws ServletException, IOException {
// 1、在服务器代码中new一个Cookie对象
Cookie cookie = new Cookie("key1", "value1");
Cookie cookie2 = new Cookie("key2", "value2");
// 2、调用response.addCookie( cookie对象 );
response.addCookie(cookie);
response.addCookie(cookie2);// 把cookie的信息,添加到响应头,发送给客户端保存修改。
response.getWriter().write("已经创建好两个Cookie对象");
}

谷歌浏览器查看Cookie:

 

 火狐浏览器查看Cookie:

服务器如何获取Cookie

1、只需要在服务器代码中,调用reqeust.getCookies():Cookies[]

Cookie工具类:

/**
     * 查找指定名称的cookie对象
     *
     * @param name
     * @param cookies
     * @return 返回null,说明没有找到需要的cookie<br/>
     * 找到就返回有值
     */
    public static Cookie findCookie(String name, Cookie[] cookies) {
        if (name == null || cookies == null || cookies.length == 0) {
            return null;
        }
        // 遍历查找Cookie
        for (Cookie cookie : cookies) {
            if (name.equals(cookie.getName())) {
                return cookie;
            }
        }
        return null;
    }

获取Cookie的测试代码:

protected void getCookie(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
 
// 获取Cookie对象
Cookie[] cookies = request.getCookies();
 
// 遍历输出
for (Cookie cookie : cookies) {
response.getWriter()
.write("服务器收到Cookie[" + cookie.getName() + " : "+ cookie.getValue() + "]<br/>");
}
String cookieName = "key3";
// 你要得到一个专门的cookie
Cookie iWantCookie = CookieUtils.findCookie(cookieName, cookies);
//     for (Cookie cookie : cookies) {
//         if ("key3".equals(cookie.getName())) {
//            iWantCookie = cookie;
//            break;
//         }
//     }
// 如果找到值就不为null
if (iWantCookie != null) {
response.getWriter().write("需要的Cookie[" + cookieName + "]找到了");
} else {
response.getWriter().write("没找到我需要的Cookie[" + cookieName + "]");
}
}

Cookie值的修改

方法一:

  1. 直接new一个你需要修改的同名的cookie对象,然后在构造器上赋于新值

调用response.addCookie( cookie )通知客户端保存修改

//        方法一:
//        1、直接new一个你需要修改的同名的cookie对象,然后在构造器上赋于新值   (修改key1的cookie)
Cookie cookie = new Cookie("key1", "newValue1222222");
//        2、调用response.addCookie( cookie )通知客户端保存修改
response.addCookie(cookie);

方法二:

  • 调用reqeust.getCookies()得到全部的Cookie
  • 再遍历查找到你需要修改的Cookie对象
  • 调用setValue方法设置新的值到cookie中
  • 调用response.addCookie(cookie);保存修改
//  方法二:
//  1、调用reqeust.getCookies()得到全部的Cookie
Cookie[] cookies = request.getCookies();
//  2、再遍历查找到你需要修改的Cookie对象
Cookie iWantCookie = CookieUtils.findCookie("key2", cookies);
if (iWantCookie != null) {
// 3、调用setValue方法设置新的值到cookie中
iWantCookie.setValue("newValue2222");
// 4、调用response.addCookie(cookie);保存修改
response.addCookie(iWantCookie);
response.getWriter().write("key2的cookie已经被修改");
}

Cookie生命控制

setMaxAge();                            设置Cookie的生命时长。

正数                表示在指定的秒数后过期

负数                默认值,表示浏览器关闭后就删除Cookie

零值                表示浏览器收到响应后马上删除Cookie(不用等浏览器关闭)

正数 表示在指定的秒数后过期

protected void life3600(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  Cookie cookie = new Cookie("key4", "life3600");
  cookie.setMaxAge(60 * 60); // 让Cookie在一小时后失效(被删除)
  response.addCookie(cookie);
  response.getWriter().write("创建了一个可以存活一小时的Cookie");
}

零值 表示浏览器收到响应后马上删除Cookie(不用等浏览器关闭)

protected void deleteNow(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie[] cookies = request.getCookies();
        Cookie iWantCookie = CookieUtils.findCookie("key1", cookies);
        if (iWantCookie != null) {
            iWantCookie.setMaxAge(0); // 让浏览器马上删除Cookie
            response.addCookie(iWantCookie);// 通知客户端对Cookie进行操作
            response.getWriter().write("已经删除了key1的cookie");
        }
    }

负数  默认值,表示浏览器关闭后就删除Cookie:

  protected void defaultLife(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie cookie = new Cookie("key3", "defaultLife");
        cookie.setMaxAge(-1);// 默认值就是-1
        response.addCookie(cookie);
        response.getWriter().write("创建了一个默认生命时长的Cookie");
    }

 

Cookie有效路径Path的设置

Cookie中的path属性可以有效的过滤哪些请求下,哪些Cookie可以不用发送给服务器。

Cookie对象的path属性的默认值是当前工程路径:/工程名 

ACookie        path=/day13            表示只有访问地址为http://ip:port/day13/任意路径            这个ACookie都会发送给服务器。

BCookie        path=/day13/abc        表示只有访问地址为http://ip:port/day13/abc/任意路径        才会把这个BCookie发送给服务器。

 

举例:

ACookie        path=/day13   

BCookie        path=/day13/abc   

 

请求地址为:http://ip:port/day13/c.html           

ACookie会发送给服务器

BCookie不会发送给服务器

 

请求地址为:http://ip:port/day13/abc/c.html

ACookie  会发送给服务器

Bcookie   也会发送给服务器。

protected void testPath(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie cookie = new Cookie("testpath", "testpath");
        cookie.setPath(request.getContextPath() + "/abc");
        response.addCookie(cookie);
        response.getWriter().write("创建了一个带有路径的Cookie");
    }

Cookie练习---免输入用户名登录 :

 表单:

<body>
  <%--
    在form标签中,action属性值里不要追加请求的参数<br/>
    如果你一定要给表单添加额外的请求参数。请使用隐藏域。
   --%>
    <form action="userServlet" method="post">
      <input type="hidden" name="action" value="login"/>
        用户名:<input type="text" name="username" value="${ cookie.username.value }"/><br/>
        密 码:<input type="password" name="password"/><br/>
      <input type="submit" />
  </form>
</body>

UserServlet程序:

public class UserServlet extends BaseServlet {
    private static final long serialVersionUID = 1L;

    protected void login(HttpServletRequest request,
                         HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        if ("admin".equals(username) && "666666".equals(password)) {
            Cookie cookie = new Cookie("username", username);
            cookie.setMaxAge(60 * 60 * 24 * 7);// 让Cookie在每次成功登录后,存活一个星期
            response.addCookie(cookie);
            System.out.println("登录成功!!!");
        } else {
            System.out.println("登录失败!!!");
        }
    }

}

Cookie的运用:

//获得浏览器cookie中的购物车数据
String  cartListCookieStr = CookieUtil . getCookieValue(request,"cartListCookie",true);
if(StringUtils.isNotBlank(cartListCookieStr)){
//不为空,表示cookie中已经存在购物车数据,将老的购物车数据转换成购物车对象赋到新购物车
List<OmsCartItem> oldCartList = JSON.parseArray (cartListCookieStr , OmsCartItem.class);

将对象集合转成cookie存储( 设置cookie过期时间1天 )

List<OmsCartItem> newCartList = newArrayList<>();
 
CookieUtil.setCookie( request , response , "cartListCookie" , JSON.toJSONString(newCartList), 3600 * 24 , true);

CookieUtil:

public class CookieUtil {
    /***
     * 获得cookie中的值,默认为主ip:www.gmall.com
     * @param request
     * @param cookieName
     * @param isDecoder
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
        Cookie[] cookies = request.getCookies();
        if (cookies == null || cookieName == null){
            return null;
        }
        String retValue = null;
        try {
            for (int i = 0; i < cookies.length; i++) {
                if (cookies[i].getName().equals(cookieName)) {
                    if (isDecoder) {//如果涉及中文
                        retValue = URLDecoder.decode(cookies[i].getValue(), "UTF-8");
                    } else {
                        retValue = cookies[i].getValue();
                    }
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return retValue;
    }
    /**
     * 设置cookie的值
     * @param request
     * @param response
     * @param cookieName
     * @param cookieValue
     * @param cookieMaxage cookie生命周期:正数(表示在指定的秒数后过期)负数(默认值,表示浏览器关闭后就删除Cookie)零值(表示浏览器收到响应后马上删除Cookie(不用等浏览器关闭)
     * @param isEncode
     */
    public static   void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
        try {
            if (cookieValue == null) {
                cookieValue = "";
            } else if (isEncode) {
                cookieValue = URLEncoder.encode(cookieValue, "utf-8");
            }
            Cookie cookie = new Cookie(cookieName, cookieValue);
            if (cookieMaxage >= 0)
                cookie.setMaxAge(cookieMaxage);
            if (null != request)
                // 设置域名的cookie
                cookie.setDomain(getDomainName(request));
            // 在域名的根路径下保存
            cookie.setPath("/");
            response.addCookie(cookie);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /***
     * 获得cookie的主域名,本系统为gmall.com,保存时使用
     * @param request
     * @return
     */
    private static final String getDomainName(HttpServletRequest request) {
        String domainName = null;
        String serverName = request.getRequestURL().toString();
        if (serverName == null || serverName.equals("")) {
            domainName = "";
        } else {
            serverName = serverName.toLowerCase();
            serverName = serverName.substring(7);
            final int end = serverName.indexOf("/");
            serverName = serverName.substring(0, end);
            final String[] domains = serverName.split("\\.");
            int len = domains.length;
            if (len > 3) {
                // www.xxx.com.cn
                domainName = domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
            } else if (len <= 3 && len > 1) {
                // xxx.com or xxx.cn
                domainName = domains[len - 2] + "." + domains[len - 1];
            } else {
                domainName = serverName;
            }
        }
        if (domainName != null && domainName.indexOf(":") > 0) {
            String[] ary = domainName.split("\\:");
            domainName = ary[0];
        }
        System.out.println("domainName = " + domainName);
        return domainName;
    }
    /***
     * 将cookie中的内容按照key删除
     * @param request
     * @param response
     * @param cookieName
     */
    public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String cookieName) {
        setCookie(request, response, cookieName, null, 0, false);
    }
}

 

posted @ 2021-08-20 10:37  Vermeer  阅读(53)  评论(0)    收藏  举报