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());
}
}
}
Cookie 类源码分析笔记
最新推荐文章于 2023-04-21 06:00:00 发布