1、从存储方式上比较

Cookie中只能保存ASCII字符串,如果需要存取Unicode字符或是二进制数据,需要进行UTF-8、GBK或者BASE64等方式编码。Cookie中也不能直接存取Java对象,若要存取稍微复杂的数据,Cookie是比较困难的


而Session中可以存取任何类型的数据,包括但不限于String、Integer、List、Map等,Session中也可以直接保存Java Bean乃至任何Java类,使用起来非常方便,可以吧Session看做是一个Java容器类


base64转码实例:


<%@ page language="java" pageEncoding="UTF-8" %>

   
   

   
   

   
   
<%
    //图片放于根目录下
	File file = new File(this.getServletContext().getRealPath("cookie.gif"));
	
	// 二进制数组
	byte[] binary = new byte[(int)file.length()];
	
	// 从图片文件读取二进制数据. 
	InputStream ins = this.getServletContext().getResourceAsStream(file.getName());
	ins.read(binary);
	ins.close();
	
	// BASE64 编码
	String content = BASE64Encoder.class.newInstance().encode(binary);
	
	// 包含二进制数据的 Cookie
	Cookie cookie = new Cookie("file", content);
		
	// 将 Cookie 发送到客户端	
	response.addCookie(cookie);
%>



Cookie Encoding


从 Cookie 中获取到的二进制图片:

<script type="text/javascript">cookieArea.value=document.cookie;</script>



<%@ page language="java" pageEncoding="UTF-8" %>

   
   

   
   
<%
	// 清除输出
	out.clear();
	
	for(Cookie cookie : request.getCookies()){
	
		if(cookie.getName().equals("file")){
		
			// 从 Cookie 中取二进制数据
			byte[] binary = BASE64Decoder.class.newInstance().decodeBuffer(cookie.getValue().replace(" ", ""));
			
			// 设置内容类型为 gif 图片
			response.setHeader("Content-Type", "image/gif");
			response.setHeader("Content-Disposition", "inline;filename=cookie.gif");
			response.setHeader("Connection", "close");
			
			// 设置长度
			response.setContentLength(binary.length);
			
			// 输出到客户端
			response.getOutputStream().write(binary);
			response.getOutputStream().flush();
			response.getOutputStream().close();
			
			return;
		}
	}
	
%>



utf-8转码实例


<%@ page language="java" pageEncoding="UTF-8" %>

   
   

   
   
<%
	// 使用中文的 Cookie. name 与 value 都使用 UTF-8 编码. 
	Cookie cookie = new Cookie(
		URLEncoder.encode("姓名", "UTF-8"), 
		URLEncoder.encode("我", "UTF-8"));
		
	// 发送到客户端	
	response.addCookie(cookie);
%>



Cookie Encoding


<%
	if(request.getCookies() != null){
		for(Cookie cc : request.getCookies()){
		
			String cookieName = URLDecoder.decode(cc.getName(), "UTF-8");
			String cookieValue = URLDecoder.decode(cc.getValue(), "UTF-8");
			
			out.println(cookieName + "=");
			out.println(cookieValue + "; 
");
		}
	}
	else{
		out.println("Cookie 已经写入客户端. 请刷新页面. ");
	}
%>



2、从隐私安全上比较

Cookie存储在客户端浏览器中,对客户端是可见的,客户端的一些程序可能窥探、复制甚至修改Cookie中的内容,而Session在存储在服务器上,对客户端是透明的,不存在敏感信息泄露的危险。


如果选用Cookie,比较好的方法是敏感信息如账号密码等尽量不要写到Cookie中,最好是想谷歌百度那样讲敏感信息加密,提交到服务器后解密,保证Cookie中的信息只有自己能看得懂,而如果选择Session就省事多了,反正是放在服务器上,Session里任何隐私都可以


3、从有效期上比较

Cookie的maxAge属性支持永久登录的的效果,只需要把maxAge属性设置为一个很大的数字或是Integer..MAX_VALUE就可以了


使用Session理论也可以达到这种效果,只需要调用方法setMaxInactuveInterval(integer.MAX_VALUE)。但是由于Session依赖于名为JSESSIONID的Cookie,而该Cookie的maxAge属性默认为-1,所以只要关闭了浏览器该Session就会失效,因此Session不能实现永久登录的功能,使用URL地址重写也不行。


4、从对服务器的负担上比较

由于Session是存储在服务端的,因此对于并发访问量极高的网站(如百度,谷歌),是不太可能使用Session来跟踪客户对话的


而Cookie由于是存储在客户端的,不占用服务器资源,所以没有这方面的担忧


5、从浏览器支持上比较

Cookie需要客户端浏览器的支持,如果客户端禁用了Cookie,或者支持Cookie,则会话跟踪就会失败。对于WAP(不支持Cookie),常规的COokie则派不上用场,这时就需要使用Session以及URL重写,需要注意的是所有用到Session程序的URL重写都要使用response.encodeURL(String URL)或者response.encodeRedirectURL(String URL),否则导致Session会话失败


如果客户端支持Cookie,则Cookie可以设置为本浏览器窗口及其子窗口有效(maxAge=-1),也可以设置为所有浏览器窗口有效(maxAge=Integer.MAX_VALUE),而Session只能在本浏览器窗口及其子窗口有效。如果俩个浏览器窗口互不相干,则将使用到俩个不同的Session。


此处附上URL地址重写(代码可能有些许错误);

原理:将该用户的Session的id信息重写到URL地址中,


服务器能够解析重写后的URL获取Session的id,这样即使客户端不支持Cookie,也可以使用Session记录用户状态,例如:


">HomePage


该方法会自动判断客户端是否支持Cookie,如果客户端支持Cookie,则会将URL原封不动地输出来,否则将用户Session的id重写到URL中,重写后的输出可能是这样的:


homePage


即添加了字符串";jsessionid=XXXX"。其中XXXX是Session的id


6、从跨域名上比较

Cookie支持跨域名访问,只需要将domain属性设置为相应域名后缀(如:.baidu.com,注意此处是以“.”开头的),则以该域名为后缀的所有网站都可以访问该Cookie,而Session则不支持。