Cookie与Session机制.docx
- 文档编号:2191604
- 上传时间:2023-05-02
- 格式:DOCX
- 页数:46
- 大小:151.43KB
Cookie与Session机制.docx
《Cookie与Session机制.docx》由会员分享,可在线阅读,更多相关《Cookie与Session机制.docx(46页珍藏版)》请在冰点文库上搜索。
Cookie与Session机制
会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。
常用的会话跟踪技术是Cookie与Session。
Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
本章将系统地讲述Cookie与Session机制,并比较说明什么时候不能用Cookie,什么时候不能用Session。
本章的所有源代码均包含在项目Session中。
1 Cookie机制
在程序中,会话跟踪是很重要的事情。
理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。
例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。
而Web应用程序是使用HTTP协议传输数据的。
HTTP协议是无状态的协议。
一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。
这就意味着服务器无法从连接上跟踪会话。
即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。
要跟踪该会话,必须引入一种机制。
Cookie就是这样的一种机制。
它可以弥补HTTP协议无状态的不足。
在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。
1.1 什么是Cookie
Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。
目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。
由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。
怎么办呢?
就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。
这样服务器就能从通行证上确认客户身份了。
这就是Cookie的工作原理。
Cookie实际上是一小段的文本信息。
客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。
客户端浏览器会把Cookie保存起来。
当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。
服务器检查该Cookie,以此来辨认用户状态。
服务器还可以根据需要修改Cookie的内容。
查看某个网站颁发的Cookie很简单。
在浏览器地址栏输入javascript:
alert(document.cookie)就可以了。
JavaScript脚本会弹出一个对话框显示本网站颁发的所有Cookie的内容,如图5.1所示。
图5.1 Baidu网站颁发的Cookie
图5.1中弹出的对话框中显示的为Baidu网站的Cookie。
其中第一行BAIDUID记录的就是笔者的身份helloweenvsfei,只是Baidu使用特殊的方法将Cookie信息加密了。
%注意:
Cookie功能需要浏览器的支持。
如果浏览器不支持Cookie(如大部分手机中的浏览器)或者把Cookie禁用了,Cookie功能就会失效。
不同的浏览器采用不同的方式保存Cookie。
IE浏览器会在“C:
\DocumentsandSettings\你的用户名\Cookies”文件夹下以文本文件形式保存,一个文本文件保存一个Cookie。
1.2 记录用户访问次数
Java中把Cookie封装成了javax.servlet.http.Cookie类。
每个Cookie都是该Cookie类的对象。
服务器通过操作Cookie类对象对客户端Cookie进行操作。
通过request.getCookie()获取客户端提交的所有Cookie(以Cookie[]数组形式返回),通过response.addCookie(Cookiecookie)向客户端设置Cookie。
Cookie对象使用key-value属性对的形式保存用户状态,一个Cookie对象保存一个属性对,一个request或者response同时使用多个Cookie。
因为Cookie类位于包javax.servlet.http.*下面,所以JSP中不需要import该类。
看一个使用Cookie记录用户账号以及登录次数的例子。
在MyEclipse中新建WebProject,选择JavaEE5.0规范,填写项目名称为sessionWeb。
新建JSP页面cookie.jsp,输入源代码如下:
代码5.1 cookie.jsp
<%@pagelanguage="java"pageEncoding="UTF-8"errorPage="login.jsp"%>
<%
request.setCharacterEncoding("UTF-8"); //设置request编码
Stringusername=""; //用户名
intvisitTimes=0; //访问次数
Cookie[]cookies=request.getCookies(); //所有的Cookie
for(inti=0;cookies!
=null&&i //遍历Cookie寻找账号与登录次数 Cookiecookie=cookies[i]; //第i个Cookie if("username".equals(cookie.getName())){//如果Cookie名为username username=cookie.getValue(); //则记录该Cookie的内容 } elseif("visitTimes".equals(cookie.getName())){ //如果Cookie名为visitTimes visitTimes=Integer.parseInt(cookie.getValue()); //则记录Cookie的内容 } } if(username==null||username.trim().equals("")){ //如果没有找到用户名,则转到登录界面 thrownewException("您还没有登录。 请先登录"); } //修改Cookie,更新用户的访问次数 CookievisitTimesCookie=newCookie("visitTimes",Integer.toString (++visitTimes)); response.addCookie(visitTimesCookie); //覆盖名为visitTimes的Cookie %> DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">
10px;">
您的账号: | <%=username%> |
登录次数: | <%=visitTimes%> |
"location='<%=request.getRequestURI()%>? ts='+ newDate().getTime();"class="button"> |
程序使用Cookie记录用户的访问次数。
如果用户没有登录,则显示登录界面。
工作原理是程序先检查Cookie,如果没有找到包含username属性的Cookie,则抛出异常,页面跳转到errorPage指定的错误处理页面login.jsp。
login.jsp源代码如下:
代码5.2 login.jsp
<%@pagelanguage="java"pageEncoding="UTF-8"isErrorPage="true"%>
<%
request.setCharacterEncoding("UTF-8"); //设置request编码方式
response.setCharacterEncoding("UTF-8");//设置response编码方式
if("POST".equals(request.getMethod())){//如果是以POST方式登录
CookieusernameCookie= //新建名为username的Cookie
newCookie("username",request.getParameter("username"));
CookievisittimesCookie=newCookie("visitTimes","0");
//新建Cookie
response.addCookie(usernameCookie);//添加到response中
response.addCookie(visittimesCookie); //response会将Cookie发送
给客户端
response.sendRedirect(request.getContextPath()+"/cookie.jsp"); //显示Cookie页面
return;
}
%>
DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">
10px;">
red;"><%=exception.get Message()%> | |
账号: | 200px;"> |
密码: | "width: 200px;"> |
"button"> |
程序运行效果如图5.2所示。
图5.2 使用Cookie记录用户访问次数
客户端A与客户端B都可能访问该程序,A会提交A的Cookie,B会提交B的Cookie。
代码request.getCookies()并没有指明获取谁的Cookie。
这句代码取的是谁的Cookie呢?
答案是A执行时取的是A的Cookie,B执行时取的是B的Cookie。
这是Cookie机制规定的。
程序只需要简单执行request.getCookies()就可以了,服务器只会返回当前客户的Cookie,而不会返回其他客户的Cookie。
各客户端的Cookie彼此独立,互不可见。
1.3 Cookie的不可跨域名性
很多网站都会使用Cookie。
例如,Google会向客户端颁发Cookie,Baidu也会向客户端颁发Cookie。
那浏览器访问Google会不会也携带上Baidu颁发的Cookie呢?
或者Google能不能修改Baidu颁发的Cookie呢?
答案是否定的。
Cookie具有不可跨域名性。
根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。
Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。
Cookie在客户端是由浏览器来管理的。
浏览器能够保证Google只会操作Google的Cookie而不会操作Baidu的Cookie,从而保证用户的隐私安全。
浏览器判断一个网站是否能操作另一个网站Cookie的依据是域名。
Google与Baidu的域名不一样,因此Google不能操作Baidu的Cookie。
需要注意的是,虽然网站与网站同属于Google,但是域名不一样,二者同样不能互相操作彼此的Cookie。
%注意:
用户登录网站之后会发现访问时登录信息仍然有效,而普通的Cookie是做不到的。
这是因为Google做了特殊处理。
本章后面也会对Cookie做类似的处理。
1.4 Unicode编码:
保存中文
中文与英文字符不同,中文属于Unicode字符,在内存中占4个字符,而英文属于ASCII字符,内存中只占2个字节。
Cookie中使用Unicode字符时需要对Unicode字符进行编码,否则会乱码。
编码可以使用.URLEncoder类的encode(Stringstr,Stringencoding)方法,解码使用.URLDecoder类的decode(Stringstr,Stringencoding)方法,例如:
代码5.3 encoding.jsp
<%@pagelanguage="java"pageEncoding="UTF-8"%>
directive.pageimport=".URLEncoder"/> directive.pageimport=".URLDecoder"/> <% //使用中文的Cookie.name与value都使用UTF-8编码 Cookiecookie=newCookie( URLEncoder.encode("姓名","UTF-8"), URLEncoder.encode("刘京华","UTF-8")); response.addCookie(cookie);//发送到客户端 %> DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">
<%
if(request.getCookies()!
=null){
for(Cookiecc:
request.getCookies()){ //遍历所有的Cookie
StringcookieName=URLDecoder.decode(cc.getName(),"UTF-8");
StringcookieValue=URLDecoder.decode(cc.getValue(),"UTF-8");
out.println(cookieName+"="+cookieValue+";
");
}
}
else{
out.println("Cookie已经写入客户端.请刷新页面.");
}
%>
程序使用UTF-8编码了Cookie内容,然后再使用UTF-8解码Cookie并显示出来。
程序运行效果如图5.3所示。
图5.3 Cookie的UTF-8编码
%提示:
Cookie中保存中文只能编码。
一般使用UTF-8编码即可。
不推荐使用GBK等中文编码,因为浏览器不一定支持,而且JavaScript也不支持GBK编码。
1.5 BASE64编码:
保存二进制图片
Cookie不仅可以使用ASCII字符与Unicode字符,还可以使用二进制数据。
例如在Cookie中使用数字证书,提供安全度。
使用二进制数据时也需要进行编码。
下面的例子使用BASE64编码在Cookie中保存二进制文件。
源代码如下:
代码5.4 base64.jsp
<%@pagelanguage="java"pageEncoding="UTF-8"%>
directive.pageimport="sun.misc.BASE64Encoder"/> directive.pageimport="java.io.InputStream"/> directive.pageimport="java.io.File"/> <% Filefile=newFile(this.getServletContext().getRealPath("cookie. gif")); byte[]binary=newbyte[(int)file.length()]; //二进制数组 //从图片文件读取二进制数据. InputStreamins=this.getServletContext().getResourceAsStream (file.getName()); ins.read(binary); ins.close(); Stringcontent=BASE64Encoder.class.newInstance().encode(binary); //BASE64编码 Cookiecookie=newCookie("file",content); //包含二进制数据的Cookie response.addCookie(cookie); //将Cookie发送到客户端 %> DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">
从Cookie中获取到的二进制图片:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Cookie Session 机制