会话技术(cookie和session的理解)

会话技术(cookie和session的理解)

首先,我要举个贴近现实的例子,这个例子通俗易懂,有助于理解cookie和session的本质

例子
咖啡店有活动,消费满5杯赠1杯。但一般不会一次就喝5杯,一般是一次一次去的。但是咖啡店店员不会记得每个人的消费情况(http协议无状态),所以可以给每位顾客分配一张信息卡,用来记录顾客的消费记录,这样一来,就解决了顾客每次来记不清消费记录的情况(解决http的无状态)。但是还存在一个问题,就是这个信息卡的记录谁来记,假如顾客记的话,顾客拥有的卡片不能记那么多信息(cookie存储大小的限制),再者有的顾客不诚实,在自己的卡片上多写了几杯(cookie的信息保存在浏览器不安全)。所以,有一个解决办法,就是顾客的卡片不记录消费信息,只记录一个标识号,当顾客再次来,只需要带着这张卡(cookie),出示这张卡的标识号(sessionid),咖啡店借助这个标识号来到电脑的记录里查相应的信息,就可以知道顾客所有的消费记录了。但需要注意的是,顾客带的这张卡,只有在本店,分店,总店才起作用(cookie的携带路径),而且必须在这张卡的有效期内(cookie的失效),有效期有的是本次消费活动(会话级别),有的可能是一年内(持久化),如果这张卡丢了或者是过期了,咖啡店对应这张卡的信息还会保留,只不过顾客和咖啡店失去关联了,顾客就不能再享受优惠了,咖啡店的信息会在检查不到标识号的一段时间后销毁,或者顾客在有效期内主动销毁(session的销毁)。顾客如果第一次去,如果有需要,咖啡店会帮顾客开办一张卡,把卡号告诉顾客,把信息保存在咖啡店的电脑记录里。以后去的话,顾客拿着这张卡,出示卡号,咖啡店就可以调出相关信息了(session的创建和获取)。

会话
会话之所以出现,是因为http协议是无状态的,一次请求响应(连接)之后就与服务器断开,连接与连接没有关联,要想有关联,就有了会话机制。这机制必须是客户端和服务端同时支持才可以,服务器例如tomcat提供了javax.servlet.http.Cookie的api,主流浏览器都支持了cookie。

Cookie
会话技术从原理上是cookie支持的,因为连接肯定涉及客户端与服务端,客户端就支持着cookie。实现cookie,就是在服务端有cookie的api,在服务端创建cookie对象,把信息,时效,携带路径(作用范围)这三个必须的要素封装进cookie,然后通过respnose的响应头传给浏览器,浏览器就可以管理cookie,等下次访问的时候,浏览器检查时效和携带路径符合的话,通过request的请求头再传递给服务器。
但是cookie也有缺点:第一,因为交互都在请求头响应头上,所以存储大小肯定有限制,不能存更多的信息。第二,因为cookie是浏览器维护的,面向用户,所以不安全。

Session
鉴于cookie的缺点,session才产生。Session解决cookie的缺点,就是考虑,能不能不把信息存在维护cookie的浏览器(客户端)里,而存在后台?再者,会话技术必须是基于cookie的,怎么实现?解决办法就是,cookie里只存一个标识,一个客户端服务端用来交互的标识,其他重要信息存在服务器的一个对象里,这样前台传来cookie的标识,后台就拿到这个标识与自己比对,比对上了就可以拿出对应的信息,这个对象就是session,这个标识就是sessionid。当客户端第一次访问,请求头没有cookie,进入服务端,tomcat引擎校验请求,生成request,request知道请求里是否含有cookie,当需要用到会话技术时,session通过request.getSession()获得,其实就是检查请求里有没有携带sessionid的cookie,第一次没有,就创建一个session和一个sessionid,再把需要保存的信息存在这个session里,最后服务器会自动为你把sessionid的cookie通过响应返给客户端,注意,仅仅是sessionid的cookie。当客户端在以后的访问中,cookie被带到服务端,tomcat引擎解析cookie中的sessionid,当request.getSession()时,request请求里有sessionid,就不会创建新的session,而是跟据sessionid去检索对应的session出来,检索不到就创建一个新的,再从中获取需要的信息。
但注意,Session仅仅只是保存记录的载体,依赖于cookie的,携带路径和时效是cookie决定而不是session。Cookie才是实现会话技术的基础,而session是为了解决数据安全和浏览器压力才应运而生的技术,其实也是必然。另外,创建和获取session只能通过request.getSession()。还应注意一点,如果在不同客户端上访问服务器,会生成不同的sessionid,因为保存sessionid的cookie是浏览器维护的,比如第一次用谷歌访问,返回的cookie是谷歌保存的,再用火狐访问,火狐肯定没有这个cookie,所以会再创建一个不同的sessionid,sessionid是uuid生成的32位随机数。

cookie的API使用:

服务器端cookie的创建
只能存非中文

Cookie cookie = new Cookie(String cookieName,String cookieValue);

设置cookie的时效,单位为秒
默认是负数,代表是会话级别,cookie存在浏览器内存中,浏览器关闭即销毁
设置为0,代表销毁此cookie,但携带路径和时效也必须一致
设置为正数,代表将cookie持久化到本地(浏览器会指定本机的一个文件夹)
cookie失效只与设置的时间有关

cookie.setMaxAge(int seconds);

设置cookie的携带路径
示例:
cookie.setPath("/MyWeb")
代表访问MyWeb应用中的任何资源都携带cookie
cookie.setPath("/MyWeb/cookieServlet")
代表访问MyWeb中的cookieServlet时才携带cookie信息
如果不设置携带路径(默认),那么该cookie信息会在访问产生该cookie的 web资源所在的路径都携带cookie信息。例如访问/MyWeb/demo/cookieServlet,生成cookie,那么再次访问demo下的资源才会携带cookie,访问/WEB16/index.jsp则不会。

cookie.setPath(String path);

向客户端发送cookie
将cookie存在response的响应头里

response.addCookie(Cookie cookie);

服务器端接收cookie
前提必须符合cookie的时效和携带路径
后台可以创建很多cookie*

Cookie[] cookies = request.getCookies();

session的API使用:

获得Session对象

HttpSession session = request.getSession();

向session中存取数据及删除(session也是一个域对象)

session.setAttribute(String name,Object obj);
session.getAttribute(String name);
session.removeAttribute(String name);

session的销毁
1.服务器(非正常)关闭时
2.session过期/失效(默认30分钟)
默认的配置在tomcat的web.xml
时间的起算点:
从不操作服务器端的资源开始计时
如需另作配置,在工程的web.xml中自定义配置

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

3.手动销毁session

session.invalidate();

作用范围:
默认在一次会话中,也就是说,一次会话中任何资源(请求的url)共用一个session对象

引出的问题:
浏览器关闭,session就销毁了?
这是不正确的
浏览器关不关闭,跟服务器端的session根本没关系,session销毁只能通过以上三种方式。

jsessionid的持久化(其实就是自己定义cookie)

假如服务器端第一次创建session,服务器默认会帮你生成一个会话级别的cookie返给客户端,当浏览器关闭,cookie丢失,访问服务器时没有jsessionid去匹配session,那么就会使用uuid再生成一个jsessionid,同时也创建一个新的session区域,之前的session区域还会存在,直到过期失效才销毁。
如果需要自定义cookie的时效和携带路径,可以自行设置,只要把jsessionid封装进这个cookie。
jsessionid的持久化:

HttpSession session = request.getSession();
String id = session.getId()
Cookie cookie = new Cookie("JSESSIONID",id);
cookie.setPath("/自定义的携带路径/");
cookie.setMaxAge(60*10);//时效,单位是秒
response.addCookie(cookie);//此时浏览器不会默认帮你创建cookie了

默认不设置path的时候,只会在请求和servlet同路径的情况下才会携带cookie中存储的数据,包含同级目录和下级目录:
在http://localhost:8080/cookie_session/test/HelloServlet中通过addCookie添加cookie数据在访问http://localhost:8080/cookie_session/test/test.html和
http://localhost:8080/cookie_session/test/test/test.html的时候都会携带cookie数据
在http://localhost:8080/cookie_session/test2/test.html中则不会携带cookie数据
只看test

参考文档:
https://blog.csdn.net/h19910518/article/details/79348051
https://blog.csdn.net/FU250/article/details/79227702

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值