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.java和SessionDemo2.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在不同的服务器程序中共享数据来获得生成的验证码,如下: