5.3 Cookie对象的应用实例

前面介绍了JSP读写Cookie信息的基础知识,但是还没有涉及具体的应用,下面通过两个具体的实例来帮助读者进一步学习。

【例5-1】在JSP中使用Cookie。该实例有writeCookie.jsp和readCookie.jsp两文件。其中writeCookie.jsp用于写入Cookie,readCookie.jsp用于读取Cookie。

writeCookie.jsp写一个Cookie到客户端,代码如下:

执行结果如图5-2所示。

图5-2 writeCookie.jsp的执行结果

readCookie.jsp代码如下:

readCookie.jsp必须注意两个问题:一是读入Cookie数组时需要判断是否为null,如果为空就不能进行下一步的操作,只能显示出Cookie为空的错误信息;二是对Cookie数组的长度进行判断,如果Cookie.length==0,说明该客户端浏览器不支持Cookie。

在写完Cookie的10分钟之内,readCookie.jsp页面的执行结果如图5-3所示。超过10分钟,该Cookie就会被浏览器删除。

图5-3 readCookie.jsp的执行结果

如果没有执行writeCookie.jsp,而直接执行readCookie.jsp,那么将显示“没有Cookie”字样,如图5-4所示。

图5-4 直接执行readCookie.jsp的结果

【例5-2】Cookie的作用是在客户端保存用户的信息,供用户下一次访问服务器的程序时使用。本例由包括个程序,CookieJSP.jsp创建并保存Cookie,ShowCookie.jsp取得客户端所有Cookie信息,并在页面上显示。

CookieJSP.jsp代码如下:

注意:如果不设置Cookie的保存时间,Cookie不会保存在硬盘内。

ShowCookie.jsp的代码如下所示:

CookieJSP.jsp的运行结果如图5-5所示。

图5-5 CookieJSP.jsp的运行结果

单击“显示Cookie值”链接,执行结果如图5-6所示。

图5-6 ShowCookie.jsp的执行结果

在地址栏中输入http://localhost:8080/ch05/CookieJSP.jsp?name=tom,然后单击“显示Cookie值”链接,执行结果如图5-7所示。

图5-7 输入name后ShowCookie.jsp的执行结果

打开另一个浏览器,直接输入http://localhost:8080/ch05/ShowCookie.jsp地址访问Cookie的值,如图5-8所示。

图5-8 直接运行ShowCookie.jsp的执行结果

刷新http://localhost:8080/ch05/ShowCookie.jsp页面,结果如图5-9所示。

图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代码如下:

jsessionid2.jsp代码如下:

如果Cookie没有禁用,在浏览器地址栏中看到的地址是这样的:http://localhost:8080/ch05/jsessionid2.jsp;如果禁用了Cookie,则看到:http://localhost:8080/ch05/jsessionid2.jsp;jsessionid=989A54B6B8DAD17453C36C79C32748EE,如图5-10所示。

图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代码如下:

usingCookie.jsp代码如下:

responseCookie.jsp代码如下:

查看usingCookie.html网页,在表单中输入所需资料信息,单击“发送资料”按钮,如图5-11所示。在表单中输入的数据被存储至Cookie当中,接下来转至responseCookie.jsp,将Cookie数据取出并在浏览器中显示,如图5-12所示。

图5-11 提交用户信息

图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>

即可解决中文乱码问题。