Cookie 类源码分析笔记

import java.io.Serializable;
import java.text.MessageFormat;
import java.util.ResourceBundle;

public class Cookie implements Cloneable, Serializable {
    /**
     * serialVersionUID适用于Java的序列化机制。
     * 简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。
     * 在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,
     * 如果相同就认为是一致的,可以进行反序列化,
     * 否则就会出现序列化版本不一致的异常,即是InvalidCastException。
     * */
    private static final long serialVersionUID = -6454587001725327448L;
    private static final String TSPECIALS; // 存储用于过滤的字符
    // 字符串文件
    private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings";
    // ResourceBundle 读取 properties 后缀的文件
    private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.http.LocalStrings");
    private String name;      // 键
    private String value;     // 值
    private String comment;   // cookie注解部分
    private String domain;    // cookie的有效域
    private int maxAge = -1;  // cookie在浏览器上保存的最大秒数
    private String path;      // cookie访问路径
    private boolean secure;   // cookie是否只能采取安全协议传送
    private int version = 0;  // cookie采用的协议版本
    private boolean isHttpOnly = false;

    /**
     * 说明:构造函数,传入一个键值对
     * @param name  键
     * @param value 值
     * */
    public Cookie(String name, String value) {
        if (name != null && name.length() != 0) { // 判空
            // 对name进行一些校验判断
            if (this.isToken(name)
                    && !name.equalsIgnoreCase("Comment")
                    && !name.equalsIgnoreCase("Discard")
                    && !name.equalsIgnoreCase("Domain")
                    && !name.equalsIgnoreCase("Expires")
                    && !name.equalsIgnoreCase("Max-Age")
                    && !name.equalsIgnoreCase("Path")
                    && !name.equalsIgnoreCase("Secure")
                    && !name.equalsIgnoreCase("Version")
                    && !name.startsWith("$")) {
                this.name = name;
                this.value = value;
            } else {
                // 获取错误信息 Cookie name \"{0}\" is a reserved token
                String errMsg = lStrings.getString("err.cookie_name_is_token");
                Object[] errArgs = new Object[]{name}; // 创建一个错误对象数组,将名字丢进去
                /**
                 * 方法原型:String MessageFormat.format(String fmt, Object...args)
                 * 该方法是格式化字符串:比如-> MessageFormat.format("hello {0}"," world");
                 * 将返回:hello world
                 * */
                errMsg = MessageFormat.format(errMsg, errArgs);
                // 抛出不合法参数异常 Cookie名称{0}是一个保留的标记
                throw new IllegalArgumentException(errMsg);
            }
        } else {
            // 抛出异常 Cookie名称不能为空或为空
            throw new IllegalArgumentException(lStrings.getString("err.cookie_name_blank"));
        }
    }

    /**
     * 说明:判断值是不是保留得令牌数据
     * @param value
     * @return boolean
     * */
    private boolean isToken(String value) {
        int len = value.length();

        for(int i = 0; i < len; ++i) {
            char c = value.charAt(i);  // 拿到value每个字符
            // TSPECIALS 内存储过滤字符,如果存在则认为value无效
            if (c < ' ' || c >= 127 || TSPECIALS.indexOf(c) != -1) {
                return false;
            }
        }
        return true;
    }

    static {
        // System.getProperty该方法用于获取系统变量
        if (Boolean.valueOf(System.getProperty("org.glassfish.web.rfc2109_cookie_names_enforced", "true")))
            TSPECIALS = "/()<>@,;:\\\"[]?={} \t";
        else TSPECIALS = ",; ";
    }

    public void setComment(String purpose) {
        this.comment = purpose;
    }

    public String getComment() {
        return this.comment;
    }

    public void setDomain(String domain) {
        this.domain = domain.toLowerCase();
    }

    public String getDomain() {
        return this.domain;
    }

    public void setMaxAge(int expiry) {
        this.maxAge = expiry;
    }

    public int getMaxAge() {
        return this.maxAge;
    }

    public void setPath(String uri) {
        this.path = uri;
    }

    public String getPath() {
        return this.path;
    }

    public void setSecure(boolean flag) {
        this.secure = flag;
    }

    public boolean getSecure() {
        return this.secure;
    }

    public String getName() {
        return this.name;
    }

    public void setValue(String newValue) {
        this.value = newValue;
    }

    public String getValue() {
        return this.value;
    }

    public int getVersion() {
        return this.version;
    }

    public void setVersion(int v) {
        this.version = v;
    }
    
    public void setHttpOnly(boolean isHttpOnly) {
        this.isHttpOnly = isHttpOnly;
    }
    
    public boolean isHttpOnly() {
        return this.isHttpOnly;
    }

    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException var2) {
            throw new RuntimeException(var2.getMessage());
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值