Cookie机制与在JavaEE中的使用和实现

关于cookie机制你只需要知道这些

1.  cookie是由服务器端生成的,并且可以对cookie进行基本的操作
2.  浏览器能够识别服务器端传输过来的cookie,并存储服务器端传输过来的cookie
3.  浏览器的每次请求都会携带cookie回服务器,服务器能够识别浏览器请求携带过来的cookie,且能够在响应中携带这些cookie返回给浏览器
4.  服务器端的会话状态是由session实现的,而session是由cookie去定位。每一个会话对应一个session,每一个session对应一个id,而每个id对应一个名为JSESSIONID的cookie(是的,cookie有名字,cookie的name就是cookie的key,是cookie的唯一标识),有了cookie机制才有了session机制

创建cookie

//创建cookie
Cookie cookie = new Cookie(cookieName, cookieValue);

Cookie只有一个有参构造方法,所以在创建cookie时必须指定cookie的名称和所对应的值
这里写图片描述
上图就是我访问百度时,百度服务器创建并返回给浏览器的cookie,可以看出百度的服务器创建了很多不同用途的cookie

设置cookie的生命周期

//设置cookie的路径
cookie.setMaxAge(-1);
数字 解释
-1 cookie的生命周期受浏览器窗口限制,浏览器窗口不关闭cookie就一直存在,窗口关闭,cookie销毁
0 浏览器接收到cookie的那一刻就立即销毁了cookie,因为生命时长只有0秒
3600 不管浏览器关闭多少次,cookie会存在3600s,即一小时整,时间一到即销毁cookie

设置cookie的域

//设置cookie的域
cookie.setDomain(domainName);

设置cookie的域并不是必要的,但在需要解决cookie跨域问题的项目里就是必要的。默认不设置的情况下,cookie的域为当前访问的域名,服务器只能获取域为当前域及其父域下的cookie,下面举几个详细的对比案例,✘为接收不到cookie,✔️为能接收到cookie

1.访问zaomianbao.com
操作 zaomianbao.com blog.zaomianbao.com test.blog.zaomianbao.com
不设置 ✔️ ✔️ ✔️
cookie.setDomain(“.zaomianbao.com”) ✔️ ✔️ ✔️
cookie.setDomain(“.blog.zaomianbao.com”) ✔️ ✔️
cookie.setDomain(“.test.blog.zaomianbao.com”) ✔️
2.访问blog.zaomianbao.com
操作 zaomianbao.com blog.zaomianbao.com test.blog.zaomianbao.com
不设置 ✔️ ✔️
cookie.setDomain(“.zaomianbao.com”) ✔️ ✔️ ✔️
cookie.setDomain(“.blog.zaomianbao.com”) ✔️ ✔️
cookie.setDomain(“.test.blog.zaomianbao.com”) ✔️
3.访问test.blog.zaomianbao.com
操作 zaomianbao.com blog.zaomianbao.com test.blog.zaomianbao.com
不设置 ✔️
cookie.setDomain(“.zaomianbao.com”) ✔️ ✔️ ✔️
cookie.setDomain(“.blog.zaomianbao.com”) ✔️ ✔️
cookie.setDomain(“.test.blog.zaomianbao.com”) ✔️

注:设置域名前面带点是规范,RFC2109中提到:The value for the Domain attribute contains no embedded dots or does not start with a dot,即cookie的domain的值,必须是以点开始的,不以点开始的cookie,应该拒绝丢弃。(如果不严格,不带点也可以)

设置cookie的路径

//设置cookie的路径
cookie.setPath("/");

cookie的path默认是当前我们访问的页面,那么当设置为”/”时即为cookie在同一个应用下共享。总结就是:domain决定在哪个域下共享,path决定在哪个路径下共享。

将cookie传给浏览器

//将创建的cookie放入HttpServletResponse中响应回浏览器
response.addCookie(cookie);

将服务器创建的cookie放入response中,服务器的响应就会携带添加进来的cookie返回给浏览器

服务器获取请求中的cookie

//获取请求中携带过来的cookie
Cookie[] cookieList = request.getCookies();

当浏览器再次访问我们应用下的页面是,就会再次发送请求给我们的服务器,那么服务器就可以通过以上方法获得当前domain以及父domain的cookie

删除cookie
//cookie没有删除方法,只有通过控制生命周期为0间接销毁浏览器上存储的对应的cookie
cookie.setMaxAge(0);
response.addCookie(cookie);
下面提供一个操作cookie的工具类
package util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 *  descri: cookie工具类
 *  author: LiuChengxiang
 */
public class CookieUtil {
    /**
     *  获取cookie
     */
    public static String getCookie(HttpServletRequest request, String cookieName, String encodeString) {
        Cookie[] cookieList = request.getCookies();
        if (cookieList == null || cookieName == null) {
            return null;
        }
        String retValue = null;
        try {
            for (int i = 0; i < cookieList.length; i++) {
                if (cookieList[i].getName().equals(cookieName)) {
                    retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {
             e.printStackTrace();
        }
        return retValue;
    }

    /**
     * 创建并设置cookie
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response,String cookieName, String cookieValue, int cookieMaxage, String encodeString) {
        try {
            if (cookieValue == null) {
                cookieValue = "";
            } else {
                cookieValue = URLEncoder.encode(cookieValue, encodeString);
            }
            Cookie cookie = new Cookie(cookieName, cookieValue);
            if (cookieMaxage > 0)
                cookie.setMaxAge(cookieMaxage);
            if (null != request) {
                String domainName = getDomainName(request);
                System.out.println(domainName);
                if (!"localhost".equals(domainName)) {
                    cookie.setDomain(domainName);
                }
            }
            cookie.setPath("/");
            response.addCookie(cookie);
        } catch (Exception e) {
             e.printStackTrace();
        }
    }

    /**
     * 获取域名
     */
    private static 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);
            int end = serverName.indexOf("/");
            serverName = serverName.substring(0, end);
            String[] domains = serverName.split("\\.");
            int len = domains.length;
            if (len > 3) {
                domainName = "." + domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
            } else if (len < 4 && len > 1) {
                domainName = "." + domains[len - 2] + "." + domains[len - 1];
            } else {
                domainName = serverName;
            }
            if(isNumeric(domains[len-1])){
                domainName = serverName;
            }
        }

        if (domainName != null && domainName.indexOf(":") > 0) {
            String[] ary = domainName.split("\\:");
            domainName = ary[0];
        }
        return domainName;
    }

    /**
     * 判断数字
     */
    private static boolean isNumeric(String str){
        for (int i = str.length();--i>=0;){
            if (!Character.isDigit(str.charAt(i))){
                return false;
            }
        }
        return true;
    }

}

如有错误,评论区下指正

猜你喜欢

转载自blog.csdn.net/weixin_37490221/article/details/80785543