一、会话的概念

  会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。
  有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾经来过,这称之为有状态会话。

二、会话过程中要解决的一些问题?

  每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,程序要想办法为每个用户保存这些数据。

三、Cookie

 

Cookie机制

        在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。

        而Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。要跟踪该会话,必须引入一种机制。Cookie就是这样的一种机制。它可以弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。

什么是Cookie

       Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。

        Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。


servlet之cookied/session深入浅出(cookie)_编程

  Cookie的有效期

Cookie的maxAge决定着Cookie的有效期,单位为秒(Second)。Cookie中通过getMaxAge()方法与setMaxAge(int maxAge)方法来读写maxAge属性。

如果maxAge属性为正数,则表示该Cookie会在maxAge秒之后自动失效。浏览器会将maxAge为正数的Cookie持久化,即写到对应的Cookie文件中。无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该Cookie仍然有效。下面代码中的Cookie信息将永远有效。

 

Cookie cookie = new Cookie("username","helloweenvsfei");   // 新建Cookie

cookie.setMaxAge(Integer.MAX_VALUE);           // 设置生命周期为MAX_VALUE

response.addCookie(cookie);                    // 输出到客户端

 

如果maxAge为负数,则表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。maxAge为负数的Cookie,为临时性Cookie,不会被持久化,不会被写到Cookie文件中。Cookie信息保存在浏览器内存中,因此关闭浏览器该Cookie就消失了。Cookie默认的maxAge值为–1。

如果maxAge为0,则表示删除该Cookie。Cookie机制没有提供删除Cookie的方法,因此通过设置该Cookie即时失效实现删除Cookie的效果。失效的Cookie会被浏览器从Cookie文件或者内存中删除,

 

例如:

Cookie cookie = new Cookie("username","helloweenvsfei");   // 新建Cookie

cookie.setMaxAge(0);                          // 设置生命周期为0,不能为负数

response.addCookie(cookie);                    // 必须执行这一句

 

response对象提供的Cookie操作方法只有一个添加操作add(Cookie cookie)。

要想修改Cookie只能使用一个同名的Cookie来覆盖原来的Cookie,达到修改的目的。删除时只需要把maxAge修改为0即可。

 

注意:从客户端读取Cookie时,包括maxAge在内的其他属性都是不可读的,也不会被提交。浏览器提交Cookie时只会提交name与value属性。maxAge属性只被浏览器用来判断Cookie是否过期。

 

 Cookie的修改、删除

Cookie并不提供修改、删除操作。如果要修改某个Cookie,只需要新建一个同名的Cookie,添加到response中覆盖原来的Cookie。

如果要删除某个Cookie,只需要新建一个同名的Cookie,并将maxAge设置为0,并添加到response中覆盖原来的Cookie。注意是0而不是负数。负数代表其他的意义。读者可以通过上例的程序进行验证,设置不同的属性。

 

注意:修改、删除Cookie时,新建的Cookie除value、maxAge之外的所有属性,例如name、path、domain等,都要与原Cookie完全一样。否则,浏览器将视为两个不同的Cookie不予覆盖,导致修改、删除失败。

四、使用范例

本文工程免费下载

新建一个web项目,项目整个结构如下:

servlet之cookied/session深入浅出(cookie)_编程_02

1.CookiedServlet.Java

 

[java]  view plain  copy
 
  1. package com.mucfc;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import java.util.Date;  
  6.   
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.http.Cookie;  
  9. import javax.servlet.http.HttpServlet;  
  10. import javax.servlet.http.HttpServletRequest;  
  11. import javax.servlet.http.HttpServletResponse;  
  12.   
  13. /** 
  14.  * cookied测试 
  15.  * @author 林炳文Evankaka(
  16.  * @since 2015.6.24 
  17.  */  
  18. public class CookiedServlet extends HttpServlet {  
  19.   
  20.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  21.             throws ServletException, IOException {  
  22.   
  23.         //设置浏览器以UTF-8编码进行接收,解决中文乱码问题  
  24.         response.setContentType("text/html;charset=UTF-8");  
  25.         PrintWriter out = response.getWriter();  
  26.         //获取浏览器访问访问服务器时传递过来的cookie数组  
  27.         Cookie[] cookies = request.getCookies();  
  28.         //如果用户是第一次访问,那么得到的cookies将是null  
  29.         if (cookies!=null) {  
  30.             out.write("您上次访问的时间是:");  
  31.             for (int i = 0; i < cookies.length; i++) {  
  32.                 Cookie cookie = cookies[i];  
  33.                 if (cookie.getName().equals("lastAccessTime")) {  
  34.                     Long lastAccessTime =Long.parseLong(cookie.getValue());  
  35.                     Date date = new Date(lastAccessTime);  
  36.                     out.write(date.toLocaleString());  
  37.                 }  
  38.             }  
  39.         }else {  
  40.             out.write("这是您第一次访问本站!");  
  41.         }  
  42.           
  43.         //用户访问过之后重新设置用户的访问时间,存储到cookie中,然后发送到客户端浏览器  
  44.         Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");//创建一个cookie,cookie的名字是lastAccessTime  
  45.         //将cookie对象添加到response对象中,这样服务器在输出response对象中的内容时就会把cookie也输出到客户端浏览器  
  46.         response.addCookie(cookie);  
  47.     }  
  48.   
  49.   
  50.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  51.             throws ServletException, IOException {  
  52.   
  53.      doGet(request,response);  
  54.     }  
  55.   
  56. }  

2、web.xml配置

 

 

[html]  view plain  copy
 
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">  
  3.   <display-name>ServletCookied</display-name>  
  4.   <servlet>  
  5.     <servlet-name>CookiedServlet</servlet-name>  
  6.     <servlet-class>com.mucfc.CookiedServlet</servlet-class>  
  7.   </servlet>  
  8.   
  9.   <servlet-mapping>  
  10.     <servlet-name>CookiedServlet</servlet-name>  
  11.     <url-pattern>/servlet/CookiedServlet</url-pattern>  
  12.   </servlet-mapping>  
  13.   <welcome-file-list>  
  14.     <welcome-file>index.html</welcome-file>  
  15.     <welcome-file>index.htm</welcome-file>  
  16.     <welcome-file>index.jsp</welcome-file>  
  17.     <welcome-file>default.html</welcome-file>  
  18.     <welcome-file>default.htm</welcome-file>  
  19.     <welcome-file>default.jsp</welcome-file>  
  20.   </welcome-file-list>  
  21. </web-app>  

3、运行结果:firefox浏览器中输入http://lin-pc:8080/ServletCookied/servlet/CookiedServlet

 

首次输入是第一次访问,接下来刷新,就会显示上次访问的时间了。

servlet之cookied/session深入浅出(cookie)_编程_03

这里还可以看浏览器中的cookied,方法如下,打开上面的网址不变

servlet之cookied/session深入浅出(cookie)_编程_04

servlet之cookied/session深入浅出(cookie)_编程_05

servlet之cookied/session深入浅出(cookie)_编程_06

这里可以看到记录的cookied:lastAccessTime。内容就是值,这里加密了,只有浏览器能解读

对应 代码为:

 

[java]  view plain  copy
 
  1. //用户访问过之后重新设置用户的访问时间,存储到cookie中,然后发送到客户端浏览器  
  2.    Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");//创建一个cookie,cookie的名字是lastAccessTime  
  3.    //将cookie对象添加到response对象中,这样服务器在输出response对象中的内容时就会把cookie也输出到客户端浏览器  
  4.    response.addCookie(cookie);  

在上面的例子中,在程序代码中并没有使用setMaxAge方法设置cookie的有效期,所以当关闭浏览器之后,cookie就失效了,要想在关闭了浏览器之后,cookie依然有效,那么在创建cookie时,就要为cookie设置一个有效期。如下所示:

 

 

[java]  view plain  copy
 
  1. //用户访问过之后重新设置用户的访问时间,存储到cookie中,然后发送到客户端浏览器  
  2.      Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");//创建一个cookie,cookie的名字是lastAccessTime  
  3.      //设置Cookie的有效期为1天  
  4.      cookie.setMaxAge(24*60*60);  
  5.      //将cookie对象添加到response对象中,这样服务器在输出response对象中的内容时就会把cookie也输出到客户端浏览器  
  6.      response.addCookie(cookie);  

五、Cookie注意细节
  1. 一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
  2. 一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
  3. 浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
  4. 如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
本文工程免费下载