会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。
有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾经来过,这称之为有状态会话。
每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,程序要想办法为每个用户保存这些数据。
在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。
而Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。要跟踪该会话,必须引入一种机制。Cookie就是这样的一种机制。它可以弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。
什么是Cookie
Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
Cookie的有效期
Cookie的maxAge决定着Cookie的有效期,单位为秒(Second)。Cookie中通过getMaxAge()方法与setMaxAge(int maxAge)方法来读写maxAge属性。
如果maxAge属性为正数,则表示该Cookie会在maxAge秒之后自动失效。浏览器会将maxAge为正数的Cookie持久化,即写到对应的Cookie文件中。无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该Cookie仍然有效。下面代码中的Cookie信息将永远有效。
Cookie cookie = new Cookie("username","helloweenvsfei"); // 新建Cookie
cookie.setMaxAge(Integer.MAX_VALUE); // 设置生命周期为MAX_VALUE
response.addCookie(cookie); // 输出到客户端
如果maxAge为负数,则表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。maxAge为负数的Cookie,为临时性Cookie,不会被持久化,不会被写到Cookie文件中。Cookie信息保存在浏览器内存中,因此关闭浏览器该Cookie就消失了。Cookie默认的maxAge值为–1。
如果maxAge为0,则表示删除该Cookie。Cookie机制没有提供删除Cookie的方法,因此通过设置该Cookie即时失效实现删除Cookie的效果。失效的Cookie会被浏览器从Cookie文件或者内存中删除,
例如:
Cookie cookie = new Cookie("username","helloweenvsfei"); // 新建Cookie
cookie.setMaxAge(0); // 设置生命周期为0,不能为负数
response.addCookie(cookie); // 必须执行这一句
response对象提供的Cookie操作方法只有一个添加操作add(Cookie cookie)。
要想修改Cookie只能使用一个同名的Cookie来覆盖原来的Cookie,达到修改的目的。删除时只需要把maxAge修改为0即可。
注意:从客户端读取Cookie时,包括maxAge在内的其他属性都是不可读的,也不会被提交。浏览器提交Cookie时只会提交name与value属性。maxAge属性只被浏览器用来判断Cookie是否过期。
Cookie的修改、删除
Cookie并不提供修改、删除操作。如果要修改某个Cookie,只需要新建一个同名的Cookie,添加到response中覆盖原来的Cookie。
如果要删除某个Cookie,只需要新建一个同名的Cookie,并将maxAge设置为0,并添加到response中覆盖原来的Cookie。注意是0而不是负数。负数代表其他的意义。读者可以通过上例的程序进行验证,设置不同的属性。
注意:修改、删除Cookie时,新建的Cookie除value、maxAge之外的所有属性,例如name、path、domain等,都要与原Cookie完全一样。否则,浏览器将视为两个不同的Cookie不予覆盖,导致修改、删除失败。
新建一个web项目,项目整个结构如下:
1.CookiedServlet.java
package com.mucfc; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * cookied测试 * @author 林炳文Evankaka(博客:http://blog.csdn.net/evankaka) * @since 2015.6.24 */ public class CookiedServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置浏览器以UTF-8编码进行接收,解决中文乱码问题 response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); //获取浏览器访问访问服务器时传递过来的cookie数组 Cookie[] cookies = request.getCookies(); //如果用户是第一次访问,那么得到的cookies将是null if (cookies!=null) { out.write("您上次访问的时间是:"); for (int i = 0; i < cookies.length; i++) { Cookie cookie = cookies[i]; if (cookie.getName().equals("lastAccessTime")) { Long lastAccessTime =Long.parseLong(cookie.getValue()); Date date = new Date(lastAccessTime); out.write(date.toLocaleString()); } } }else { out.write("这是您第一次访问本站!"); } //用户访问过之后重新设置用户的访问时间,存储到cookie中,然后发送到客户端浏览器 Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");//创建一个cookie,cookie的名字是lastAccessTime //将cookie对象添加到response对象中,这样服务器在输出response对象中的内容时就会把cookie也输出到客户端浏览器 response.addCookie(cookie); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>ServletCookied</display-name> <servlet> <servlet-name>CookiedServlet</servlet-name> <servlet-class>com.mucfc.CookiedServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CookiedServlet</servlet-name> <url-pattern>/servlet/CookiedServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
首次输入是第一次访问,接下来刷新,就会显示上次访问的时间了。
这里还可以看浏览器中的cookied,方法如下,打开上面的网址不变
这里可以看到记录的cookied:lastAccessTime。内容就是值,这里加密了,只有浏览器能解读
对应 代码为:
//用户访问过之后重新设置用户的访问时间,存储到cookie中,然后发送到客户端浏览器 Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");//创建一个cookie,cookie的名字是lastAccessTime //将cookie对象添加到response对象中,这样服务器在输出response对象中的内容时就会把cookie也输出到客户端浏览器 response.addCookie(cookie);
//用户访问过之后重新设置用户的访问时间,存储到cookie中,然后发送到客户端浏览器 Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");//创建一个cookie,cookie的名字是lastAccessTime //设置Cookie的有效期为1天 cookie.setMaxAge(24*60*60); //将cookie对象添加到response对象中,这样服务器在输出response对象中的内容时就会把cookie也输出到客户端浏览器 response.addCookie(cookie);
servlet之cookied/session深入浅出(上)
原文地址:http://blog.csdn.net/evankaka/article/details/46627335