2.3 cookie
网址重写和隐藏域都只适用于保持那些不需要跨越许多页面的信息。如果这些信息需要跨越很多页面,这两种技术就变得很难实现,因为你必须管理每一个页面的信息。值得庆幸的是,cookie能够解决网址重写和隐藏域都无法解决的问题。
cookie是自动地在Web服务器和浏览器之间来回传递的一小块信息。cookie适用于那些需要跨越许多页面的信息。由于cookie是作为HTTP标头嵌入的,因此传输它的过程由HTTP协议处理。除此之外,还可以根据自己的需要设置cookie的有效期限。对于Web浏览器而言,每台Web服务器最多可以支持20个cookie。
cookie的不足之处在于,用户可以通过修改他/她的浏览器设置来拒绝接受cookie。
要使用cookie,必须熟悉javax.servlet.http.Cookie类,以及HttpServletRequest和HttpServletResponse接口中的几个方法。
要创建cookie,传递一个名称和一个值给Cookie类的构造器:
创建Cookie之后,可以设置它的domain、path及maxAge属性。尤其值得关注的是maxAge属性,因为它决定cookie的有效期限。
为了将一个cookie发送到浏览器,需在HttpServletResponse上调用add方法:
当浏览器再次发出对同一个资源或者对同一台服务器中的不同资源的请求时,它会同时把从Web浏览器处收到的cookie再传回去。
cookie也可以利用JavaScript在客户端进行创建和删除,但是这超出了本书的内容范围。
要访问浏览器发出的cookie,可以在HttpServletRequest中使用getCookies方法。该方法将返回一个Cookie数组,如果请求中没有cookie,将返回null。为了找到某个名称的cookie,需要迭代数组。下面举个例子,看看如何读取一个名为maxRecords的cookie。
令人遗憾的是,没有getCookieByName方法可以使获取cookie变得更简单一些。更令人难过的是,也没有方法可以直接删除cookie。为了删除cookie,需要创建一个同名的cookie,将它的maxAge属性设置为0,并在HttpServletResponse中添加一个新的cookie。看看下面是如何删除一个名为userName 的cookie的:
为了举例说明如何在Session管理中使用cookie,可参见代码清单2-4中的Preference-Servlet类。这个Servlet允许用户修改4个cookie的值,从而在同一个应用程序中设定其他Servlet的显示设置。
PreferenceServlet的doGet方法发送了一个表单,其中包含几个输入域,如图2-6所示。
表单的上方有三个链接(Cookie Class、Cookie Info及Preference),可以导航到同一个应用程序的其他Servlet。稍后会简单介绍一下Cookie Class和Cookie Info。
当用户提交表单时,会调用PreferenceServlet的doPost方法。doPost方法会创建这些cookie:maxRecords、titleFontSize、titleFontStyle及titleFontWeight,并将同一个cookie的所有之前值都覆盖掉。之后,它会将用户选择的值发送给浏览器。
可以利用下面这个URL来调用PreferenceServlet:
代码清单2-5中的CookieClassServlet类和代码清单2-6中的CookieInfoServlet类,是利用PreferenceServlet设置的cookie来格式化它们的内容的。CookieClassServlet Servlet将Cookie类的属性写在一个HTML列表中。列表中的项编号由maxRecords cookie的值决定,而这个值则可以由用户利用PreferenceServlet进行设置。
CookieInfoServlet类读取titleFontSize、titleFontWeight和titleFontStyle cookie的值,将以下CSS样式写到浏览器中,这里的x、y和z是指上述cookie的值。
一个div元素用这个样式来格式化文本“Session Management with Cookies:”。
可以利用下面这个URL调用CookieClassServlet:
可以通过将浏览器跳转到下面这个URL,来调用CookieInfoServlet servlet:
图2-7和图2-8分别展示了CookieClassServlet和CookieInfoServlet的结果。