Session与Cookie的“前世今生”

苦于在学Filter过滤器的时候,突然发现先前的Cookie与Session基础不太扎实,也想去更深入地了解一下,一起去了解一下吧。

先列出思维导图,会着重对其中的关键点进行详细说明:
在这里插入图片描述

Cookie详解

概念及简介

客户端会话技术,将数据保存到客户端
http协议本身是一种无状态的协议,不能进行登录验证。

  1. cookie是按照域名分别存储的,从A域名得到的cookie只会发送回A域名。
  2. cookie分为临时cookie和长久cookie。如果一个cookie没有设置有效期,那么浏览器在关闭时就会删除这个cookie,这种cookie叫做临时cookie,如果cookie设置了有效期,那么浏览器会一直保存这个cookie,直到有效期为止,这种cookie叫做长久cookie。
  3. cookie常用于存储用户的登录信息。

快速入门

  1. 创建Cookie对象,绑定数据
   new Cookie(String name, String value) 
  1. 发送Cookie对象
response.addCookie(Cookie cookie) 
  1. 获取Cookie,拿到数据
  Cookie[]  request.getCookies()  

实现原理

基于响应头set-cookie和请求头cookie实现
Cookie是对http协议的扩展。 服务端可以在响应头中添加 Set-Cookie字段,将cookie值发送给客户端,浏览器在收到这个响应时,会自动将cookie保存起来,下次再发送请求时,会将这个cookie附带在请求头的Cookie字段中发给服务器。

经典例题

  1. 一次可不可以发送多个cookie?
    可以
    可以创建多个Cookie对象,使用response调用多次addCookie方法发送cookie即可。

  2. cookie在浏览器中保存多长时间?
    默认情况下,当浏览器关闭后,Cookie数据被销毁
    可以用持久化存储解决:
    setMaxAge(int seconds)

    1. 正数:将Cookie数据写到硬盘的文件中。持久化存储。并指定cookie存活时间,时间到后,cookie文件自动失效
    2. 负数:默认值
    3. 零:删除cookie信息
  3. cookie能不能存中文?

    • 在tomcat 8 之前 cookie中不能直接存储中文数据。
    • 需要将中文数据转码—一般采用URL编码(%E3)
    • 在tomcat 8 之后,cookie支持中文数据。特殊字符还是不支持,建议使用URL编码存储,URL解码解析
  4. cookie共享问题?
    1.假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享?
    回答:默认情况下cookie不能共享
    解决方案:
    setPath(String path)😗*设置cookie的获取范围。默认情况下,设置当前的虚拟目录
    如果要共享,则可以将path设置为"/"

    2. 不同的tomcat服务器间cookie共享问题?
    答案:setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享。
    setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享.

Session详解

背景及简介

cookie技术可以将信息存储在不同的浏览器中,并且可以实现多次请求下的数据共享。但是如果传输的信息比较多的情况下,使用cookie技术会增加服务器端程序处理的难度,这时我们就可以采用session技术。
session是一种将会话数据保存到服务器端的技术。 对Tomcat而言,Session是一块在服务器开辟的内存空间,其存储结构为ConcurrentHashMap
session是一种建立在cookie之上的通信状态保留机制,可以实现在服务端存储某个用户的一些信息。

工作原理

那么Session在何时创建呢
当然还是在服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同创建Session的方法,而在Java中是通过调用HttpServletRequest的getSession方法(使用true作为参数)创建的。
在创建了Session的同时,服务器会为该Session生成唯一的Session id,而这个Session id在随后的请求中会被用来重新获得已经创建的Session;

在Session被创建之后,就可以调用Session相关的方法往Session中增加内容了,而这些内容只会保存在服务器中,发到客户端的只有Session id;当客户端再次发送请求的时候,会将这个Session id带上,服务器接受到请求之后就会依据Session id找到相应的Session,从而再次使用之。
问题细化:
创建
sessionid第一次产生是在直到某server端程序调用 ==HttpServletRequest.getSession(true)==这样的语句时才被创建。

删除
超时;程序调用HttpSession.invalidate();程序关闭;

session存放在哪里
服务器端的内存中。不过session可以通过特殊的方式做持久化管理(memcache,redis)。

session的id是从哪里来的,sessionID是如何使用的
当客户端第一次请求session对象时候,服务器会为客户端创建一个session,并将通过特殊算法算出一个session的ID,用来标识该session对象

session会因为浏览器的关闭而删除吗?
不会,session只会通过上面提到的方式去关闭。

举例说明原理

tomcat服务器为例。
ManagerBase是所有session管理工具类的基类,它是一个抽象类,所有具体实现session管理功能的类都要继承这个类,该类有一个受保护的方法,该方法就是创建sessionId值的方法:

tomcat的session的id值生成的机制是一个随机数加时间加上jvm的id值,jvm的id值会根据服务器的硬件信息计算得来,因此不同jvm的id值都是唯一的),
StandardManager类是tomcat容器里默认的session管理实现类,
它会将session的信息存储到web容器所在服务器的内存里。
PersistentManagerBase也是继承ManagerBase类,它是所有持久化存储session信息的基类,PersistentManager继承PersistentManagerBase,但是这个类只是多了一个静态变量和一个getName方法,目前看来意义不大,对于持久化存储session,tomcat还提供了StoreBase的抽象类,它是所有持久化存储session的基类,另外tomcat还给出了文件存储FileStore和数据存储JDBCStore两个实现。

快速入门

获取Session对象:
1.

HttpSession s = request.getSession(true);
注:
 当flag为true时,先查看请求当中是否有sessionId,如果没有
sessionId,则创建一个session对象;如果有sessionId,则
依据该sessionId去查找对应的session对象,如果找到了,则
返回该session对象,如果没有找到,则创建一个新的session对象。

2.`

HttpSession s = request.getSession(false);
注:
 当flag为false,先查看请求当中是否有sessionId,如果没有,
返回null;如果有sessionId,则依据该sessionId去查找对应的
session对象,如果找到了,则返回该session对象,如果没有找到,
返回null。
HttpSession s = request.getSession();
等价于 request.getSesion(true)。实际工作中一般常用这个。

使用Session进行状态管理

a.将数据绑订到session对象上:
 session.setAttribute(String name,Object obj);
b.依据绑订名获得绑订值:
 Object session.getAttribute(String name);
c.解除绑订:
 session.removeAttribute(String name);

Session超时
是什么?

服务器会把空闲时间过长的session对象从内存当中删除。
为了节省内存空间。
注:
	空闲时间一般是半个小时。

修改超时时间

方式一: 修改web.xml
 <session-config>
     <session-timeout>30</session-timeout>
 </session-config>:
 每一个web应用都有一个web.xml,另外,容器也有一个
 web.xml。
方式二: session.setMaxInactiveInterval(int seconds);:
	用于设置两次请求之间最大的间隔时间长度,如果超过这个
时间长度,服务器会将session删除。

删除Session

session.invalidate();

经典例题

1. 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
答案:默认情况下。不是。

  • 如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。
   Cookie c = new Cookie("JSESSIONID",session.getId());
           c.setMaxAge(60*60);
           response.addCookie(c);
#

2.客户端不关闭,服务器关闭后,两次获取的session是同一个吗
答案: 不是同一个,但是要确保数据不丢失。tomcat自动完成以下工作
* session的钝化:在服务器正常关闭之前,将session对象系列化到硬盘上
* session的活化:在服务器启动后,将session文件转化为内存中的session对象即可。
3.session什么时候被销毁
答案:
1. 服务器关闭
2. session对象调用invalidate() 。
3. session默认失效时间 30分钟
选择性配置修改

  <session-config>
           <session-timeout>30</session-timeout>
       </session-config>

Cookie与Session比较

**1. session存储数据在服务器端,Cookie在客户端
2. session没有数据大小限制,Cookie有
3. session数据安全,Cookie相对于不安全
**

Session一致性

何为一致性?

只要用户不重启浏览器,每次http短连接请求,理论上服务端都能定位到session,保持会话。

分布式Session

单服务器web应用中,session信息只需存在该服务器中,这是我们前几年最常接触的方式,但是近几年随着分布式系统的流行,单系统已经不能满足日益增长的百万级用户的需求,集群方式部署服务器已在很多公司运用起来,当高并发量的请求到达服务端的时候通过负载均衡的方式分发到集群中的某个服务器,这样就有可能导致同一个用户的多次请求被分发到集群的不同服务器上,就会出现取不到session数据的情况,于是session的共享就成了一个问题。

解决方案

保证session一致性的架构设计常见方法:

session同步法:多台web-server相互同步数据


客户端存储法:一个用户只存储自己的数据


反向代理hash一致性:四层hash和七层hash都可以做,保证一个用户的请求落在一台web-server上


后端统一存储:web-server重启和扩容,session也不会丢失

END,各位有什么更快理解的方法可以告诉我!!!
长路漫漫,JAVA为伴!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值