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 会帮你在网站上所打的文字或是一些选择, 都纪 ...
随机推荐
- spirngMVC的搭建
1 springMVC的搭建肯定是需要用到一系列的jar包的,那么第一步就是去spring官网下载对应版本的jar包 可以通过 http://www.cnblogs.com/imentors/p/49 ...
- 基础进阶(一)之HashMap实现原理分析
HashMap实现原理分析 1. HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端. 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二 ...
- tornado之Hello world
#!/usr/bin/env python26 #-*- coding:utf8 -*- import tornado.httpserver import tornado.ioloop import ...
- Runtime的理解与实践
Runtime是什么?见名知意,其概念无非就是"因为 Objective-C 是一门动态语言,所以它需要一个运行时系统--这就是 Runtime 系统"云云.对博主这种菜鸟而言,R ...
- 【手记】让Fiddler抓取入站请求,或者叫用Fiddler做反向代理
注意:本文不涉及HTTPS的场景 最近在弄公众号开发,除了主动去调公众号接口,还存在公众号后台要反过来调你的情形,攻受转换一线间.对于回调的情况,想要知道对方是怎样来请求的很有必要.此前经常用Fidd ...
- SUCTF--WEB
题目:flag 在哪? 介绍:网址(http://23.106.143.230/a_real_babyweb.php) 1,打开网址,抓包可以发现在 HTTP 头里面有 Cookie:suctf{Th ...
- Maven3 快速入门
Maven3 快速入门 Maven 是目前大型项目构建的必备知识.本章会通过介绍 Maven 的作用,Maven 的基本语法,以及搭建企业级项目架构来快速入门 Maven .前两部分是理论知识只需要了 ...
- 《Linux命令行与shell脚本编程大全》第十四章 处理用户输入
有时还会需要脚本能够与使用者交互.bash shell提供了一些不同的方法来从用户处获得数据, 包括命令行参数,命令行选项,以及直接从键盘读取输入的能力. 14.1 命令行参数 就是添加在命令后的数据 ...
- Mac下面的SecureCRT以及破解方案详解
今天安装SecureCRT时遇到了一些问题,解决后便想分享给大家.本人还是在校大学生,如果有说得不好的地方请多多指教. 第一步:下载:https://macabc.com/detail.htm?app ...
- 纯Socket(BIO)长链接编程的常见的坑和填坑套路
本文章纯属个人经验总结,伪代码也是写文章的时候顺便白板编码的,可能有逻辑问题,请帮忙指正,谢谢. Internet(全球互联网)是无数台机器基于TCP/IP协议族相互通信产生的.TCP/IP协议族分了 ...