![JSP应用与开发技术(第3版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/554/31794554/b_31794554.jpg)
5.3 Cookie对象的应用实例
前面介绍了JSP读写Cookie信息的基础知识,但是还没有涉及具体的应用,下面通过两个具体的实例来帮助读者进一步学习。
【例5-1】在JSP中使用Cookie。该实例有writeCookie.jsp和readCookie.jsp两文件。其中writeCookie.jsp用于写入Cookie,readCookie.jsp用于读取Cookie。
writeCookie.jsp写一个Cookie到客户端,代码如下:
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P149_76258.jpg?sign=1739156021-7DRjLxvKkMydyWRsMSVpd9rO0P4Qun16-0-c69cc32a2348749b07323da5ffea8003)
执行结果如图5-2所示。
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P149_14751.jpg?sign=1739156021-qgdJpUH8yQneSwJRbmZHqT0QwD4PmgXX-0-e3723d17e3daf25969514ca4b4d07670)
图5-2 writeCookie.jsp的执行结果
readCookie.jsp代码如下:
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P150_76260.jpg?sign=1739156021-44LLTNX9RRl7YAmnLJs3PKzfliMpzkR9-0-fab9953b373eeacbff741838e8c68360)
readCookie.jsp必须注意两个问题:一是读入Cookie数组时需要判断是否为null,如果为空就不能进行下一步的操作,只能显示出Cookie为空的错误信息;二是对Cookie数组的长度进行判断,如果Cookie.length==0,说明该客户端浏览器不支持Cookie。
在写完Cookie的10分钟之内,readCookie.jsp页面的执行结果如图5-3所示。超过10分钟,该Cookie就会被浏览器删除。
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P150_14992.jpg?sign=1739156021-gzMaB8tUE7yfHH1Zw6U8wS1GjfxjMJpX-0-4ba037135d25ca56c2a7ee6f7d00a9ca)
图5-3 readCookie.jsp的执行结果
如果没有执行writeCookie.jsp,而直接执行readCookie.jsp,那么将显示“没有Cookie”字样,如图5-4所示。
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P150_14993.jpg?sign=1739156021-YQp24Ytk6uAUsYXKJqNxAhsgECvc7teu-0-abebdb02a0c53e31432e77fddbc6554c)
图5-4 直接执行readCookie.jsp的结果
【例5-2】Cookie的作用是在客户端保存用户的信息,供用户下一次访问服务器的程序时使用。本例由包括个程序,CookieJSP.jsp创建并保存Cookie,ShowCookie.jsp取得客户端所有Cookie信息,并在页面上显示。
CookieJSP.jsp代码如下:
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P151_76262.jpg?sign=1739156021-VQCsAM6AC8RIC9IUIrkxNYV198eOJ6dh-0-e29cf7a002c8c6562aca4d47545b4748)
注意:如果不设置Cookie的保存时间,Cookie不会保存在硬盘内。
ShowCookie.jsp的代码如下所示:
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P152_76266.jpg?sign=1739156021-uTDkz70AvsJyS1w1XSawGWRh3Aqa6XjZ-0-95e43696b061d51318980c54ea0cfc8b)
CookieJSP.jsp的运行结果如图5-5所示。
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P152_15361.jpg?sign=1739156021-zOohFqJCQslxftJUMRghtMRnczQlXliw-0-33da19dc5a913774fedc23ebddd1f427)
图5-5 CookieJSP.jsp的运行结果
单击“显示Cookie值”链接,执行结果如图5-6所示。
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P152_15362.jpg?sign=1739156021-NkWmLIqVUpHYA8WGBjz7iGqs8pzqRKnZ-0-4245b7b41f841c8399b99c3d459dbf6c)
图5-6 ShowCookie.jsp的执行结果
在地址栏中输入http://localhost:8080/ch05/CookieJSP.jsp?name=tom,然后单击“显示Cookie值”链接,执行结果如图5-7所示。
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P152_15366.jpg?sign=1739156021-KsP9PsDY7pUhgrbD9ucsuwt0uTQCjg61-0-33b9d454359f194deb686bec394be74b)
图5-7 输入name后ShowCookie.jsp的执行结果
打开另一个浏览器,直接输入http://localhost:8080/ch05/ShowCookie.jsp地址访问Cookie的值,如图5-8所示。
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P152_15367.jpg?sign=1739156021-9Nqsru5qmoqjfgTSm9RvpZGVrvsVtPDO-0-d3ebb91e2d1eb197b3c86494d6f5e50e)
图5-8 直接运行ShowCookie.jsp的执行结果
刷新http://localhost:8080/ch05/ShowCookie.jsp页面,结果如图5-9所示。
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P152_15371.jpg?sign=1739156021-wpVH2zQpzaQzefdXmcamWnw0qqAN8wTs-0-49a810bf1163b5f79ec9dce888a4833a)
图5-9 刷新ShowCookie.jsp的执行结果
从上述执行结果可见,同一台机器的不同客户端访问都可以访问服务器保存在本地机器的Cookie。新开启的页面中未保存JSESSIONID的信息。
JSESSIONID就是客户端用来保存sessionid的变量,一般对于Web应用来说,客户端变量都会保存在Cookie中,JSESSIONID也不例外。不过与一般的Cookie变量不同,JSESSIONID是保存在内存Cookie中的,在一般的Cookie文件中是看不到。内存Cookie在打开一个浏览器窗口的时候会创建,在关闭这个浏览器窗口的时候也同时销毁。这也就解释了为什么session变量不能跨窗口使用,要跨窗口使用就需要手动把JSESSIONID保存到Cookie里面。
只有通过JSESSIONID才能使session机制起作用,而JSESSIONID又是通过Cookie来保存的。如果用户禁用了Cookie,可以通过URL重写来实现JSESSIONID的传递。JESSIONID通过这样的方式从客户端传递到服务器端,从而标识session。这样在用户禁用Cookie的时候也可以传递JSESSIONID来使用session,只不过需要每次都把JSESSIONID作为参数跟在URL后面传递。这样很麻烦,每次请求一个URL都要判断Cookie是否可用,如果禁用了Cookie,还要从URL里解析出JSESSIONID,然后跟在处理完后转到的URL后面,以保持JSESSIONID的传递。这些问题Sun已经想到了,所以提供了两个方法来使事情变得简单:response.encodeURL()和response.encodeRedirectURL()。这两个方法会判断Cookie是否可用,如果禁用了会解析出URL中的JSESSIONID,并连接到指定的URL后面,如果没有找到JSESSIONID会自动生成一个。这两个方法在判断是否要包含JSESSIONID的逻辑上会稍有不同。在调用response.sendRedirect之前,应该先调用response.encodeURL()或encodeRedirectURL()方法,否则可能会丢失sesssion信息。
【例5-3】服务器使用URL重写。jsessionid1.jsp利用了response对象内的encodeURL方法,将URL做了一个编码动作。jsessionid2.jsp显示sessionID。
jsessionid1.jsp代码如下:
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P153_76274.jpg?sign=1739156021-NiVsxS8i3ayVjlcbqcpwHIpr9nd9oBQW-0-ae0889bbec79ea2408c4cf9cb31bd600)
jsessionid2.jsp代码如下:
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P153_76275.jpg?sign=1739156021-T1rfPiRECTXmshLvWQv8YBc32c1j14GZ-0-0a5e5d837a538495bc6b7621a6720b1f)
如果Cookie没有禁用,在浏览器地址栏中看到的地址是这样的:http://localhost:8080/ch05/jsessionid2.jsp;如果禁用了Cookie,则看到:http://localhost:8080/ch05/jsessionid2.jsp;jsessionid=989A54B6B8DAD17453C36C79C32748EE,如图5-10所示。
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P153_15434.jpg?sign=1739156021-smDTPgUpZ8Cgz69v50xa1mat4i1mQWi9-0-8af26fa2726c400a1b725886f4342336)
图5-10 禁用Cookie时jsessionid1.jsp的执行结果
注意,JSESSIONID跟一般的URL参数传递方式是不同的,不是作为参数跟在“?”后面,而是紧跟在URl后面用“;”来分隔。
【例5-4】应用Cookie保留用户提交的信息。这个例子包含3个文件,usingCookie.html文件是一个HTML表单,其中布置了几种可供用户选取及输入个人数据的表单选项。usingCookie.jsp网页取得上述表单传送过来的变量数据,并将这些数据存入Cookie当中,然后将网页定向responseCookie.jsp。responseCookie.jsp网页程序会取得稍早存储在Cookie中的用户数据,并加以变化输出至浏览器。
usingCookie.html代码如下:
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P154_76276.jpg?sign=1739156021-aUHmjFCSZcNb7nP70bEOoY0CiKnb0Fok-0-d5fc47414a09f3eb2a0cb0bcfe079073)
usingCookie.jsp代码如下:
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P155_76278.jpg?sign=1739156021-ewOKXnNRGw9Fq2kg0GOYOGNPguYFokBr-0-4eff3db693f54dd22e4238dfbae27ba3)
responseCookie.jsp代码如下:
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P155_76279.jpg?sign=1739156021-C3jLYBa3TkRzdTAxFY2Rw1OZWyz3UOHo-0-5c1df98f1a66be68b103065fec19338f)
查看usingCookie.html网页,在表单中输入所需资料信息,单击“发送资料”按钮,如图5-11所示。在表单中输入的数据被存储至Cookie当中,接下来转至responseCookie.jsp,将Cookie数据取出并在浏览器中显示,如图5-12所示。
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P156_16068.jpg?sign=1739156021-x686O4P3a3NlE2SfUrjPFlNvxOSrje9v-0-1b3b375d14bfd9791e02ff92d71a2fc2)
图5-11 提交用户信息
![](https://epubservercos.yuewen.com/B91E50/17214369404807006/epubprivate/OEBPS/Images/Figure-P156_16069.jpg?sign=1739156021-Fykebk8xd5SBrRQCFEulmw6b4FZC59j1-0-3575b98366c2f61b7d9e22db7c52c2a2)
图5-12 应用Cookie保存用户信息
在第4章学习了session对象,通常采用session对象来保存用户的信息,可以在多个页面之间跳转时保持有效,而此例采用Cookie对象来保存用户的信息。usingCookie.jsp把用户信息存入Cookie当中,responseCookie.jsp读取Cookie中的用户数据,可以得到和session对象同样的效果。
另外,可以在usingCookie.jsp中使用setMaxAge()方法设置Cookie对象的存在期限。这样Cookie对象就会保存在硬盘中的Cookies文件夹中,用户可以不用从usingCookie.html登录,直接打开responseCookie.jsp就可以读取Cookie中的用户数据。不论浏览器是否关闭,或者服务器是否重启,只要该文件还存在,就会一直保留用户的信息。Cookie和session的关系以及Cookies和session有什么本质区别请大家查阅相关资料,这里不再详述。
在此例中还存在一个问题,就是如果输入的用户名是中文的话会出现乱码,虽然在第6章有解决中文乱码的方法,但是在这里并不适用。若想解决乱码问题,可以采用如下方法。
使用java.net.URLEncoder.encode()对要传递的中文进行编码,在传参数之前先把参数进行转码,java.net.URLEncoder.encode(param);取值时用语句java.net.URLDecoder.decode(param);再转回中文。
把usingCookie.jsp中创建Cookie的代码
Cookie nameCookie = new Cookie("name", strname);
改为:
Cookie nameCookie = new Cookie("name", java.net.URLEncoder.encode(strname));
把responseCookie.jsp中显示用户名的代码
<font color="<%=color%>" size="5"><%=name%></font>
改为:
<font color="<%=color%>" size="5"><%=java.net.URLDecoder.decode(name)%></font>
即可解决中文乱码问题。