一、会话
1.提出问题
HTTP协议是一种无状态的协议。Web服务器本身不能识别哪些请求是同一浏览器发出的,浏览器的每一次请求都是孤立的。即使HTTP1.1支持持续连接,但当用户有一段时间没有提交请求,连接也会关闭。作为Web服务器,必须能够采用一种机制来唯一地标识一个用户,同时记录该用户的状态。
2.会话和会话状态
Web应用会话: 指一个客户端浏览器与服务器之间连续发生的一系列请求和响应过程。
Web会话状态: 指Web服务器与浏览器会在会话过程中产生的状态信息,借助会话状态,服务器会把属于同一会话中的一系列的请求和响应过程关联起来。
二、保存会话数据的两种技术
1.Cookie
Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再访问服务器中的Web资源时,就会带着各自的数据去。这样Web资源处理的就是用户各自的数据了。
2.Session
Session是服务端技术,利用这个技术,服务器可以在运行时为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器Web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其他Web资源时在从用户各自的Session中取出数据为用户服务。
三、Cookie
1.Cookie的机制
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户的状态,就使用Response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再次请求该网站时,浏览器把请求的地址连同Cookie一同提交给服务器。服务器检查Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
2.Cookie相关API
- Cookie(String name, String value)
实例化Cookie对象,传入cooke名称和cookie的值 - public String getName()
获取Cookie的名字 - public String getValue()
获取Cookie的值 - public void setValue(String newValue)
设置Cookie的值 - public void setMaxAge(int expiry)
设置Cookie的最大保存时间,即cookie的有效期。当服务器给浏览器回送一个cookie时,如果在服务器端没有调用setMaxAge方法设置cookie的有效期,那么cookie的有效期只在一次会话过程中有效,用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一次会话,当用户关闭浏览器,会话就结束了,此时cookie就会失效,如果在服务器端使用setMaxAge方法设置了cookie的有效期,比如设置了30分钟,那么当服务器把cookie发送给浏览器时,此时cookie就会在客户端的硬盘上存储30分钟,在30分钟内,即使浏览器关了,cookie依然存在,在30分钟内,打开浏览器访问服务器时,浏览器都会把cookie一起带上,这样就可以在服务器端获取到客户端浏览器传递过来的cookie里面的信息了,这就是cookie设置maxAge和不设置maxAge的区别,不设置maxAge,那么cookie就只在一次会话中有效,一旦用户关闭了浏览器,那么cookie就没有了。那么浏览器是怎么做到这一点的呢,我们启动一个浏览器,就相当于启动一个应用程序,而服务器回送的cookie首先是存在浏览器的缓存中的,当浏览器关闭时,浏览器的缓存自然就没有了,所以存储在缓存中的cookie自然就被清掉了,而如果设置了cookie的有效期,那么浏览器在关闭时,就会把缓存中的cookie写到硬盘上存储起来,这样cookie就能够一直存在了。 - public int getMaxAge()
获取Cookies的有效期 - public void setPath(String uri)
设置cookie的有效路径,比如把cookie的有效路径设置为"/xdp",那么浏览器访问"xdp"目录下的web资源时,都会带上cookie,再比如把cookie的有效路径设置为"/xdp/gacl",那么浏览器只有在访问"xdp"目录下的"gacl"这个目录里面的web资源时才会带上cookie一起访问,而当访问"xdp"目录下的web资源时,浏览器是不带cookie的 - public String getPath()
获取cookie的有效路径 - public void setDomain(String pattern)
设置cookie的有效域 - public String getDomain()
获取cookie的有效域
response接口也中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。 同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。
3.Cookie的基本使用
下面使用Cookie记录上次访问时间。
public void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ resp.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=UTF-8"); PrintWriter out = resp.getWriter(); //获取用户的时间Cookie Cookie[] cookies = req.getCookies(); if(cookies != null){ out.print("您上次访问时间是: " ); for(int i = 0;i < cookies.length;i++){ if(cookies[i].getName().equals("lastAccessTime")){ long cookieValue = Long.parseLong(cookies[i].getValue());//得到用户上次访问时间 Date date = new Date(cookieValue); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒"); String dateValue = sdf.format(date); out.print(dateValue); } } } else{ //第一次访问时 out.print("这是您第一次访问"); } //更新Cookie Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis() + ""); //设置Cookie的时间以秒为单位 cookie.setMaxAge(3600); cookie.setPath("/CookieTest"); resp.addCookie(cookie); }
结果:
4.Cookie细节
(1)Cookie机制采用的是在客户端保持 HTTP 状态信息的方案。
(2)Cookie是在浏览器访问WEB服务器的某个资源时,由WEB服务器在HTTP响应消息头中附带传送给浏览器的一个小文本文件。
(3)一旦WEB浏览器保存了某个Cookie,那么它在以后每次访问该WEB服务器时,都会在HTTP请求头中将这个Cookie回传给WEB服务器。
(4)底层的实现原理: WEB服务器通过在HTTP响应消息中增加Set-Cookie响应头字段将Cookie信息发送给浏览器,浏览器则通过在HTTP请求消息中增加Cookie请求头字段将Cookie回传给WEB服务器。
(5)一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
(6)一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
(7)浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
5.Cookie的有效期
Cookie的maxAge决定着Cookie的有效期,单位为秒(Second)。Cookie中通过getMaxAge()方法与setMaxAge(int maxAge)方法来读写maxAge属性。
如果maxAge属性为正数,浏览器会将maxAge为正数的Cookie持久化,即写到对应的Cookie文件中。无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该Cookie仍然有效。下面代码中的Cookie信息将永远有效。
如果maxAge为负数,则表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该 Cookie即失效。maxAge为负数的Cookie,为临时性Cookie,不会被持久化,不会被写到Cookie文件中。Cookie信息保存在浏览器内存中,因此关闭浏览器该Cookie就消失了。Cookie默认的maxAge值为–1。
如果maxAge为0,则表示删除该Cookie。Cookie机制没有提供删除Cookie的方法,因此通过设置该Cookie即时失效实现删除Cookie的效果。失效的Cookie会被浏览器从Cookie文件或者内存中删除,
注意:从客户端读取Cookie时,包括maxAge在内的其他属性都是不可读的,也不会被提交。浏览器提交Cookie时只会提交name与value属性。maxAge属性只被浏览器用来判断Cookie是否过期。