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 会帮你在网站上所打的文字或是一些选择, 都纪 ...
随机推荐
- Maven 浅谈一
一.Maven的作用 在开发中,为了保证编译通过,我们会到处去寻找jar包,当编译通过了,运行的时候,却发现"ClassNotFoundException",我们想到的是,难道还差 ...
- B-树&B+树以及其在数据库中的应用
B-树&B+树以及其在数据库中的应用 1 .B-树定义 B-树是一种平衡的多路查找树,它在文件系统中很有用. 定义:一棵m 阶的B-树,或者为空树,或为满足下列特性的m 叉树:⑴树中每个结点至 ...
- C++静态库与动态库(转)
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA0cAAAC6CAIAAADqPKGOAAAgAElEQVR4nO2dy5WrOhREFYgjcAQ9Iw
- javaBean实体包区分
随着软件工程结构越来越复杂,单一的entity实体包无法满足业务需要,可以采取PO,BO,DTO结构来分类实体. PO (Persistent Object):与数据库表数据关联的实体. BO(Bus ...
- AutoCAD.net支持后台线程-Socket服务端
最近因为公司项目的需求,CAD作为服务端在服务器中常驻运行,等待客户端远程发送执行任务的指令,最终确认用Socket-tcp通讯,CAD需要实时监听客户端发送的消息,这时就需要开启线程执行Socket ...
- python win32 简单操作
源由 刚开始是帮朋友做一个按键精灵操作旺信的脚本,写完后各种不稳定:后来看到python可以操作win32相关的api,恰好这一段时间正在学习python,感觉练手的时候到了~~~ 下载 要注意Pyt ...
- Python 学习之路2
这是我在大学上机实验的作业 实验一 将一个正整数分解质因数.例如:输入90,打印出90=2*3*3*5. 首先,先谈下我的设计思路: 设计思路: 1. 先需判断输入的number是不是一个数字( ...
- centos 使用 beyond compare 对比工具
我这里的环境是centos7桌面版 三条命令安装beyond compare wget http://www.scootersoftware.com/bcompare-4.2.3.22587.x86_ ...
- MySQL 性能优化的最佳20多条经验分享(一)(转)
当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能.这里,我们不会讲过多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库.希望下面的这 ...
- 初识java这个小姑娘(二)
妙解垃圾回收机制 周一,早高峰. 一段考验一个人耐力.智力.开车技术以及脾气的路. 我把车开进了一个没有红绿灯的丁字路口,然后就没有然后了. 来自三个方向的大车小车开始在不大的一块空间里开始互相斗智斗 ...