cookie和session(一)
先来谈谈我对session和cookie的理解,事实上,只要你去面试web开发,面试官十有八九会问这个问题。
cookie和session经常被放在一起问,其实在我看来这两个东西完全是两个不一样的。
1.cookie是存在于浏览器,随意打开一个网址,用火狐的调试工具,随意选取一个链接,查看其请求头。你就会看到cookie的信息。如下图所示。

如上图所示,我们访问了新浪网,通过火狐浏览器的调试窗口可以看到cookie存在于请求头也就是httprequest中,并且是以键值对(数组)的形式存在。事实上,在java的servlet体系里,我们可以通过如下方式获取cookie.
HttpServletRequest req=ServletActionContext.getRequest();
Cookie[] cookies=req.getCookies();
for(int i=0;i<cookies.length;i++){
Cookie cookie=cookies[i];
System.out.println("name:"+cookie.getName()+",domain"+cookie.getDomain()+",value:"+cookie.getValue()+",maxage:"+cookie.getMaxAge());
}
我们在一个action中加入如下代码,并且访问这个action,则可以看到控制台打印出如下信息。

cookie对象有几个属性,如name,domain,value,maxage等,具体的意义可以参考servlet的api文档。
以上的请求的cookie是我首次访问某一个网站的链接时候产生的。可以看到cookie数组中只有一个元素。这边先注意一下,后续会有更进一步的说明。
说了获取cookie数组和cookie,我们一定也想知道如何把我们自己的一些信息放进cookie,其实很简单。http的一次请求总是伴随着一次响应,我们就将cookie信息放入到响应中,传递给浏览器。在java下代码是这样写的。
HttpServletResponse res=ServletActionContext.getResponse();
Cookie cookie=new Cookie("xdx", "i'm xdx");
res.addCookie(cookie);
可以看到当我们发起这个请求时,在响应头有下列信息。

也就是通过这次请求,我们把xdx=i'm xdx 这个cookie通过response放进了浏览器。
当我们在访问该网站上的其他页面的时候,在请求头都将带有这个cookie。如下图所示。

而假如我们清楚历史记录,包括cookie。

再次访问该网站的某一个地址。刚才我们加进去的cookie就不存在了。

理解这一点对我们后面解读cookie与session的关系很重要。
2.那session又是一个什么样的东西呢?在我的理解,session是一种持久的会话,它的存在主要是为了克服http无状态的特点,关于http无状态,或者说没有记忆,这里不多阐述,涉及到计算机网络的知识,简单来说就是http一次请求对应一次响应,在这个过程中会携带一些信息,但这些信息也仅仅在这个过程中有效。当一个请求结束,我们进入下一个请求的时候,上一个请求里面的信息对当前的请求就没什么意义了,因为当前的请求根本不会知道上一个请求里面所包含的信息。
那么当我们需要一些在各个请求都能公用的信息的时候,该怎么办呢?有很多办法,可以把信息存在数据库,然后每次从数据库去取出来,当然io存取会浪费很多时间,它仅仅针对大数据量。还有一种就是将这些信息存在内存当中。没错session其实就是这样一种对象,他把项目当中一些常用的信息存在内存当中,这些常用的信息通常是跟用户相关的,比如用户名,用户昵称,用户角色等。因为他们需要经常用到,所以把这些信息存在session中进行管理再好不过了。
在面试的时候,如果你不会回答,回答一个cookie是存在浏览器里,session是存储在服务器里面的准没错。
那我们来看看我们如何获取一个session呢。
在servlet体系里,我们可以用如下代码来获取session。
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession httpSession=request.getSession();
System.out.println(httpSession);
我们来查阅HttpServletRequest的源码,看看其getSession()方法。
/**
*
* Returns the current session associated with this request,
* or if the request does not have a session, creates one.
*
* @return the <code>HttpSession</code> associated
* with this request
*
* @see #getSession(boolean)
*
*/
public HttpSession getSession();
它的解释是返回当前与request关联的session,如果这个请求不存在session,就新建一个。
我们在两个请求中加入上述代码并运行,得到如下结果。

可以看到在整个项目内,这个session被共享着调用。
3.那么session和cookie到底有什么关系呢?
简单点说,每一个session对象都有一个sessionId,而在cookie数组中,又一个元素叫做JSESSIONID,服务器将session对象的sessionId,以名称叫做JSESSIONID,值为sessionId的形式存入cookie数组中,这样cookie和session就发生了关联。
上述的过程可以用类似如下的代码来实现。
HttpServletRequest req=ServletActionContext.getRequest();
HttpServletResponse res=ServletActionContext.getResponse();
Cookie cookie=new Cookie("JSESSIONID", req.getSession().getId());
当然我们并不需要写这个代码,servlet自动帮我们完成了如上的操作。
4.当我们首次某个请求的时候,servlet通过request.getSession得到当前的HttpSession,并且得到其sessionId,并且检查此时的cookie数组中是否有JSESSIONID这个cookie,如果没有的话,就将当前的sessionId作为值加入cookie数组。
我们将浏览器缓存清除,这样cookie中就没有JSESSIONID了,然后我们访问一个action。如下。

可以看到在这个请求的请求头中,cookie数组里面是不包含JSESSIONID这个cookie的,所以在响应头中servlet把它set进去了。
我们再次访问这个网站的任意action。如下图。

可以看到cookie中已经包含了JSESSIONID,并且它的值跟上一个请求set进去的是一样。
5.当我们清空浏览器的时候,session会消失吗?
这个问题经常被面试官作为进阶的问题来问应聘者,它包含着一些陷阱。因为很多时候当我们清空浏览器以后,确实需要重新登录系统才可以操作,所以很多人自然而然认为清空浏览器缓存(包含cookie)以后。session就会消失。
其实这种结论是错误的。要知道,session是存在于服务器的,你清除浏览器缓存,只是清除了cookie,跟session一点关系都没有。那么为什么我们却不能访问网站,而需要重新登录了呢?
这就是要回到我们前面说的session是如何产生的,当我们使用request.getSession()方法的时候,该方法的注释说,当session不存在的时候,servlet容器会新建一个session,那么servlet容器是如何判断session到底存不存在呢?
还记得我们发起请求的时候,请求头中cookie信息吧,没错,servlet从请求头中取出cookie,查看cookie数组中是否存在JSESSIONID这个cookie,如果没有的话,新建一个,如果有的话,在拿这个cookie的值作为sessionId去内存中寻找session,找得到的话就拿出来用,找不到就新建。
以上的逻辑可以用如下代码的模拟。
HttpServletRequest req=ServletActionContext.getRequest();
Cookie JSESSIONID=null;
Cookie[] cookies=req.getCookies();
for(int i=0;i<cookies.length;i++){
Cookie cookie=cookies[i];
if(cookie.getName().equals("JSESSIONID")){
JSESSIONID=cookie;
}
}
if(JSESSIONID==null){
createSession();//创建一个session
}else{
HttpSession session=findSessionBySessionId(JSESSIONID.getValue());//通过sessionId获取session
if(session==null){
createSession();//创建一个session
}else{
return session;
}
}
6.讨论几种极端情况。
第一种:当项目正常运行,我们清空浏览器,cookie和session会发生什么变化。
因为清空了浏览器,所以不会存在JSESSIONID这个cookie,servlet无法找到对应的session,所以他会新建一个session,然后在本次请求的响应中将session传入cookie中。
下一次请求,cookie数组中就带有JSESSIONID这个cookie了,servlet就可以找到对应的session,沿用即可。
第二种:浏览器正常,项目重启,cookie和session会发生什么变化。
因为项目重启,内存中的一切session都消失了,虽然访问一个action,请求头中有JSESSIONID这个cookie,但是通过它的值(sessionId)并不能找到session(因为根本没有),所以还是得重新创建一个session,并且这个session的sessionId跟当前cookie数组中的JSESSIONID的值不一样,所以还是得通过response去更新JSESSIONID,将之前的换成新的。
有兴趣的同学可以去试验一下。
cookie和session(一)的更多相关文章
- Cookie和Session的总结
1.开篇 在之前学习这一段的时候我一直有点没弄清楚,其实对Session这块的理解还可以,但是Cookie感觉始终还是欠缺点火候.之后的很长一段时间都基本上很少用Cookie了,渐渐的也淡忘了这一块的 ...
- java的会话管理:Cookie和Session
java的会话管理:Cookie和Session 1.什么是会话 此处的是指客户端(浏览器)和服务端之间的数据传输.例如用户登录,购物车等 会话管理就是管理浏览器客户端和服务端之间会话过程产生的会话数 ...
- Cookie和Session的那些事儿
Cookie和Session都是为了保持用户的访问状态,一方面为了方便业务实现,另一方面为了简化服务端的程序设计,提高访问性能.Cookie是客户端(也就是浏览器端)的技术,设置了Cookie之后,每 ...
- django的cookie和session以及内置信号、缓存
cookie和session cookie和session的作用: cookie和session都记录了客户端的某种状态,用来跟踪用户访问网站的整个回话.两者最大的区别是cookie的信息是存放在浏览 ...
- Cookie和Session的区别
前言 HTTP是一种无状态的协议,为了分辨链接是谁发起的,就需要我们自己去解决这个问题.不然有些情况下即使是同一个网站我们每打开一个页面也都要登录一下.而Session和Cookie就是为解决这个问题 ...
- 本地数据Store。Cookie,Session,Cache的理解。Timer类主要用于定时性、周期性任务 的触发。刷新Store,Panel
本地数据Store var monthStore = Ext.create('Ext.data.Store', { storeId : 'monthStore', autoLoad : false, ...
- Cookie与Session
再说Cookie与Session之前,先要了解一下http协议. 何为http协议: http协议即超文本传输协议,一种基于浏览器请求与服务器响应的协议,该协议主要的特点就是它是一种无状态的协议(只针 ...
- 【转】Cookie和Session区别和联系详解
会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端 ...
- 理解Cookie和Session机制(转)
目录[-] Cookie机制 什么是Cookie 记录用户访问次数 Cookie的不可跨域名性 Unicode编码:保存中文 BASE64编码:保存二进制图片 设置Cookie的所有属性 Cookie ...
- cookie 和session 的区别详解
这些都是基础知识,不过有必要做深入了解.先简单介绍一下. 二者的定义: 当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文字或是一些选择, 都纪 ...
随机推荐
- C#Session丢失问题的解决办法
关于c# SESSION丢失问题解决办法 我们在用C#开发程序的时候经常会遇到Session很不稳定,老是数据丢失.下面就是Session数据丢失的解决办法希望对您有好处.1.在WEB.CONFI ...
- CLR之委托的揭秘(二)
杂谈 在开始真正的代码之前,分析一下上周的一些工作内容,发现自己在代码上还是有很多小毛病需要纠正和去更改的,首先之前一直疏于文档的整理,几乎很少去写文档,第二对于接口开发过程中缺少一定的严谨性,很多问 ...
- 整合springboot(app后台框架搭建四)
springboot可以说是为了适用SOA服务出现,一方面,极大的简便了配置,加速了开发速度:第二方面,也是一个嵌入式的web服务,通过jar包运行就是一个web服务: 还有提供了很多metric,i ...
- 六、VueJs 填坑日记之初识*.Vue文件
上一篇博文中,我们将接口的地址通过webpack代理到了本地,解决了跨域的问题.在之前的文章中,我们一直对项目进行配置,并没有真正的切入正题,可能很多人还不明白我们要做什么?那么今天,我们就要开写代码 ...
- TensorFlow[1]:概念和简例
简介 TensorFlow是一个实现机器学习算法的接口,也是执行机器学习算法的框架.使用数据流式图规划计算流程,可以将计算映射到不同的硬件和操作系统平台. 主要概念 TensorFlow的计算可以表示 ...
- 基于Jquery UI的autocompelet改写,自动补全控件,增加下拉选项,动态设置样式,点击显示所有选项,并兼容ie6+
Jquery UI的autocompelete改写 注意:实现功能,除了原版的自动补全内容外,增加一个点击显示所有选项,样式能动态设置. 加载数据的来源为后台数据库读取. 具体代码如下: 引用 从官方 ...
- [DFS遍历图]UVA10562 Undraw the Trees
传送门: 1. UVA - 10562 2. Vjudge [看图写树] 将题目中给出的树改写为 括号表示法 即 (ROOT (SON1(...) (SON2(...)...(SONn(... ...
- 1.0-springboot的java配置方式
1.创建User实体类. @Data public class User { private String username; private String password; private Int ...
- 阿里云Https部署网站
0.开始之前 文章图片很多,注意流量 首先你得准备好一个已经备案成功的域名,并且有一个在阿里云的服务器部署了的网站. 然后就是你迫切的希望升级网站为HTTPS部署. 那么我们开始吧! 1.申请CA证书 ...
- wex5 设置文本居中或图片居中
wex5 设置文本居中 text-align:center就好了,display要设置成block 或图片居中 设置class属性的居中