会话怎么可以少了session和cookie

说在前面:

这是一篇从我个人公众号【N小王日记】转移过来的文章,是几个月之前的,虽然措辞仍然稚嫩,也不失为一篇不错的记录(风格可能更偏公众号推文一些)

最后,欢迎大家关注我!不只技术,还有生活~

 

磊哥最近应该是去南方玩耍了,应该是在抽空之中发来这样一篇小作文:

“南方的村落房屋是个性的。村民们像是商量好的似的,你用大红,我就紫红,一时间各种各样的红色扑进眼帘,让人叫不出颜色,人们却又实在地感受着巨大的差异。红色只是一个打底色,青蓝黄靛紫一股脑的泼洒其间,仿佛一个潮流张狂的都市女孩,大胆而又富有魅力。北方的村落房屋是整齐划一的。每家每户盖房子前都会认真地参考邻居的风格,他们认为统一是一种谐和的美丽。看着整片整片的红砖瓦房,就让人不禁想到大阅兵的方阵,横成排,竖成纵,动作划一,即使不会审美的人也从心底油然而生一种赞叹。”

初读一下,感觉和看过的某位作家的风格很像,颇具细心观察生活之智慧,让我忍不住引用过来。其实磊哥的思维一直是我很羡慕却又无法模仿的点,对问题的理解精准,讲话幽默而不乏深度,有丶类似于梓泉的风格,厉害。

 

 

说回正文。

有天阳光明媚,你正在某购物网开开心心的挑选商品凑单,终于选到了自己钟爱的物件凑够了9999.999元,而该网站上正好有恰好买到这个数字就减去9999元的超级活动!于是你欣欣然打开购物车,发现

只好怒删软件,世界再见。幸好这确实只是一场梦,醒来以后除去感动不说,你发现会话怎么可以少了小饼干和主菜!扯远了又。。。今天就简单谈一谈访问web时的cookie与session机制。

 

1 cookie

众所周知,Web应用是使用大名鼎鼎的HTTP协议传输数据的。HTTP协议是无状态的协议,意味着一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接,如果不采取一些措施的话,服务器将无法从连接上跟踪会话(你辛辛苦苦凑的单,说不定就躺在了别人的购物车里)。cookie就是这样的一种措施,将数据保存到客户端。抽象一点,cookie可以看作是服务器发给每一个客户的通行证,上面记录了你的一些个人信息,于是你去浏览网页的时候,网线的另一头就可以根据你的通行证知道你是谁了(突然害怕)。

 

专业一点的解释如图:

服务器上部署了两个Servlet程序CookieDemo1.java和CookieDemo2.java,姑且简称为CD1和CD2吧,CD1程序中有发送cookie的代码,CD2程序中有获取cookie的代码,当你打开浏览器访问CD1之后,服务器就会将响应头中set-cookie字段通过键值对的形式进行设置,再次在浏览器中访问CD2时,请求头中cookie字段就会包含刚刚设置的cookie信息(实际上,不管你是否有获取cookie的代码,这里的请求头中都包含这一信息),于是乎服务器就可以知道你究竟是哪一位小朋友了~

 

Java中操作cookie很方便,主要有以下3个方法,了解java语法的小朋友靠猜都能知道:

  • 创建cookie
new Cookie(String name, String value)
  • 发送cookie
response.addCookie(Cookie cookie)
  • 获取cookie
Cookie[] cookies = request.getCookies()

对于数组中的每一个cookie,getName,getValue等方法肯定会有的鸭

 

这里你可能就有疑问了,cookie究竟会保存多长时间?我说默认情况下浏览器关闭后就会被销毁,然而回忆一下平时我们网上冲浪的场景,在不登陆浏览器的情况下,我们对其所做的设置并不会因为明天重新来玩电脑打开网页时而消失不见,所以一种直觉就是cookie可以由程序写入电脑硬盘里而实现长久存储,事实也确实如此:

setMaxAge(int seconds)

对于程序员来讲,cookie的共享问题应该是最需要关心的了,假如在一个tomcat服务器中,部署了多个web项目,如果需要共享可以将 setPath(String path) 方法path设置为"/",当然为了安全考虑,默认情况下是不能共享的~。假如要使不同的tomcat服务器间共享cookie,那就必须调用 setDomain(String path) 方法设置一级域名相同啦,还是拿我最喜欢的百度来举例,百度贴吧tieba.baidu.com 和百度新闻news.baidu.com必定是部署在不同的服务器之上的,我们有 setDomain(".baidu.com") 来设置共享。

 

使用cookie的一个经典案例便是记住用户上一次访问的时间了,相信各位也会有意无意的注意到,尽管你不曾登陆过,有一些网页还是会提示上一次访问的时间,原理便也很简单,首次访问服务器时就会将cookie写回客户端保存,当你再次带着此物去访问时,服务器便可解析出相应的时间信息。公众号回复【cookie案例】即可获取此案例代码(仅供交流感情所用)。饼干虽小,足以果腹。

 

2 session

session可以用中文描述为:服务器端会话技术,在一次会话的多次请求间共享数据。和cookie对应,只不过是被保存在了服务器端的对象中,这个对象具体名字是HttpSession

 

实际上session的实现是依赖于cookie的,直接上图:

假设服务器中部署了两个Servlet程序,SessionDemo1.javaSessionDemo2.java,我们将其简称为SD1和SD2,两个程序中都有获取session的逻辑,当用户通过浏览器访问了SD1时,服务器并没有发现有session的存在,所以会在内存中创建一个新的Session对象并分配了一个编号,这里称做id,于是乎,创建一个cookie,并设置JSESSIONID等于先前分配的编号。这样一来一去的,在下一次请求时SD2时,程序就会获得这个session。

Java中使用HttpSession也很简单,经典的增删改差四君子如下:

  • 查询:
Object getAttribute(String name)
  • 增加:
void setAttribute(String name, Object value)
  • 删除:
void removeAttribute(String name)

为什么没有修改呢。。。修改和增加其实一样啊

 

看到这里可能又有疑问了。。。我们该如何操作使得用户关闭浏览器重新打开后再次访问服务器,获得同一个session?我们已经说了,session是基于cookie实现的,cookie保存了session对象的身份证号码,它可以设置存活于内存中的时间呀!于是乎,思路顺势而生:

Cookie c = new Cookie("JSESSIONID",session.getId());

c.setMaxAge(60*60);

response.addCookie(c);

同样问题有两面,服务器重启前后两次获得的session也不是同一个,但是要确保数据不丢失。tomcat自动完成活化和钝化两个操作,钝化是指将session对象系列化到硬盘上,活化则是其相反过程,将session文件转化为内存中的对象,所以这里“不是同一个”的意思应该是两次获取的session内存地址是不同的。

 

之所以将其称之为主菜,那必然是拥有比cookie更高的热量更优秀的一些特性。cookie存储数据在客户端浏览器,这必然会导致一些安全性的担忧,同样,个人电脑和服务器的性能始终是不用比较的,所以浏览器对于单个cookie 的大小有限制(4kb)且对同一个域名下的总cookie数量也有限制(20个),因此,命名之争落下帷幕。

 

有了这个工具,我们就可以实现一些“更高级”的操作,比如验证码,不难分析,我们登录时经常输入的验证码肯定是电脑自动生成的(如果是在服务器里存储成千上万张验证码的图片未免太过低级,并且浪费资源),这里就需要借助session在不同的服务器程序中共享数据来获得生成的验证码,如下:

为了节约篇幅,公众号回复【session案例】即可获取此案例代码(仅供交流感情所用)。美食是世上美好的存在,但切忌暴饮暴食,要节约资源。

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/HNU_Csee_wjw/article/details/107767967