1.cookie是首先由服务器向浏览器发送的
cookie最早来源于服务器,它像浏览器发送的响应头,如下:
HTTP/1.1 200
Server:...
Set-Cookie: name=admin
Set-Cookie: nickname=nick_admin;
Set-Cookie: email="test1@it315.org";
Set-Cookie: phone=1111111
……
每一个Cookie信息都用一个Set-Cookie头传送。实现如上效果的servlet代码如下:
Cookie ckName = new Cookie("name", name);
Cookie ckNickname = new Cookie("nickname", nickname);
ckNickname.setMaxAge(365 * 24 * 3600);
Cookie ckEmail = new Cookie("email", "test1@it315.org");
Cookie ckPhone = new Cookie("phone", "1111111");
//奇怪,针对chrome就不生成JSESSIONID
response.addCookie(ckName);
response.addCookie(ckNickname);
response.addCookie(ckEmail);
response.addCookie(ckPhone);
2.浏览器返回cookie信息
浏览器在收到服务器发送的cookie时,存储起来,并在每次向服务器请求时重新将cookie信息返回。如下:
POSE /** HTTP/1.1
accept : image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
accept-language : zh-cn
user-agent : Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; CIBA; .NET CLR 2.0.50727)
accept-encoding : gzip, deflate
host : localhost:8080
connection : Keep-Alive
Cookie: name=admin; nickname=nick_admin; email="test1@it315.org"; phone=1111111; JSESSIONID=CDF550D953DAB0E59A57D7D1CCFDDD30
3. http请求、发送小结
通过这样一来一回,返回的cookie信息是一致的(你可以改),就可以判断唯一用户了。这种方式也可以用来实现session。
读取http请求中的cookie方法如下:
String lastNickname = null;
Cookie[] cks = request.getCookies();
for (int i = 0; cks != null && i < cks.length; i++) {
if ("nickname".equals(cks[i].getName())) {
lastNickname = cks[i].getValue();
break;
}
}
或者也可以这么取
String cookieHeader = request.getHeader("Cookie");
可以通过:http://localhost:8080/Test_servlet/ch7/CookieServlet1?name=admin&nickname=nick_admin
查看效果。
3.Cookie源代码
Cookie类,真是难得一见的类,不是接口。
package javax.servlet.http;
import java.text.MessageFormat;
import java.util.ResourceBundle;
public class Cookie
implements Cloneable
{
private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings";
private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.http.LocalStrings");
private String name;
private String value;
private String comment;
private String domain;
private int maxAge = -1;
private String path;
private boolean secure;
private int version = 0;
private static final String tspecials = ",; ";
public Cookie(String name, String value)
{
if ((!(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("$")))
{
String errMsg = lStrings.getString("err.cookie_name_is_token");
Object[] errArgs = new Object[1];
errArgs[0] = name;
errMsg = MessageFormat.format(errMsg, errArgs);
throw new IllegalArgumentException(errMsg);
}
this.name = name;
this.value = value;
}
public void setComment(String purpose)
{
this.comment = purpose;
}
public String getComment()
{
return this.comment;
}
public void setDomain(String pattern)
{
this.domain = pattern.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;
}
private boolean isToken(String value)
{
int len = value.length();
for (int i = 0; i < len; ++i) {
char c = value.charAt(i);
if ((c < ' ') || (c >= '') || (",; ".indexOf(c) != -1))
return false;
}
return true;
}
public Object clone()
{
try
{
return super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e.getMessage());
}
}
}
参考:《深入体验Java_Web开发内幕-核心基础\》
……
……
分享到:
相关推荐
38 -设备部经理绩效考核表1
在做了充分的需求分析之后,将一站式电脑配件交易平台的需求分为商品管理、订单管理、配送管理、组装管理和评论管理等多个子模块,随后对系统进行设计,设计主要从系统整体架构和数据库两方面进行分析和设计,系统的核心功能主要包括商品管理、订单管理、配送管理、组装管理和评论管理,而非核心功能主要包含了用户管理和用户登录管理等模块。而后,对系统进行了编码并实现了所有功能,最后,对系统相关功能展开测试,并通过了系统测试,充分验证了系统可用性。
数据名称:2000-2022年各县市区主要社会经济发展指标面板数据 数据类型:dta格式 数据来源:中国县域统计
内容概要:本文提供了针对大学生英语竞赛写作准备的重要资源——一系列通用的英文句子模板。这些模板涵盖了现代经济社会的各种话题,从科技进步到环境保护,以及个人品质和社会责任等,并且适用于论述类文章、观点对比和个人见解的表达。文章通过对每一句话的应用环境解释和语法提示,确保使用者可以在实际写作中正确且有效地应用这些表达方式。 适合人群:正在准备参加大学生英语竞赛的学生及其他希望提高书面表达能力的学习者。 使用场景及目标:考生能够在竞赛时间内迅速构建思路完整的文章,增强语言表达的流利性和规范性;帮助学习者积累高级词汇,提升英语写作水平并培养良好的思维逻辑。 阅读建议:结合历年优秀范文进行深入学习,熟悉不同类型话题下的表述方法;练习将提供的句子融入自身创作的文章中,通过不断修订和完善来巩固记忆。同时也可以用于日常的英语写作训练当中。
本代码参考网络大神代码以及结合自身理解,编写的关于使用STM32F103C8T6芯片,通过ESP8266模块,连接阿里云物联网平台的代码历程,文件内包含了如何修改代码连接自己的设备的教程(readme.txt)文件,请读者仔细阅读。
宽带折叠传输阵天线.pdf
这是一个exe程序,解压后可以批量将Word文件转为PDF文件。
09 -单证部经理绩效考核表1
2009-2022年农村金融发展水平省级面板数据 31省份金融发展水平数据(不含港澳台地区) 涉农贷款金额亿元/第一产业增加值 30省份第一产业产值(2009-2022年) 30省份农业金融发展水平(2009-2022年)
2022年9月全国大学生英语竞赛A类初赛参考答案
Python源码03之解决对图片格式进行批量转换的问题.zip
病毒
基于向量特征的车辆轨迹预测.pdf
10-15-物控人员绩效考核表(自动计算、等级评价、任意设置)
员工末位淘汰考评表
1、操作简单,导入(待分班的数据xlsx格式),分班、导出三步。 2、分班条件设置:可选科类组合,设置起始班级和学生预设班级。 3、分班结果:班级人数均衡、男女均衡,各科成绩和总分班级均衡,最大分差不超过0.5分。 4、导出xlsx格式的分班结果。含各班单独的工作表和统计数据表。
人事档案登记及查询系统
第3课《安塞腰鼓》课件-语文八年级下册
C语言之考勤模拟系统平台(千行代码)