[size=small]由于HTTP协议的无状态特征,Web应用中经常使用Cookie和Session来保存用户在与系统交互过程中的状态数据。下面通过分析HTTP协议对Cookie和Session的工作原理加以了解。
一、Cookie
Cookie的含义是“服务器送给浏览器的甜点”,即服务器在响应请求时可以将一些数据以“键-值”对的形式通过响应信息保存在客户端。当浏览器再次访问相同的应用时,会将原先的Cookie通过请求信息带到服务器端。
下面的Servlet展示了Cookie的功能。
... ... ...
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String option = request.getParameter("option");
if ("show".equals(option)) {
//获得请求信息中的Cookie数据
Cookie[] cookies = request.getCookies();
if (cookies != null) {
//找出名称(键)为“cool”的Cookie
for (int i = 0; i < cookies.length; i++) {
if ("cool".equals(cookies[i].getName())) {
out.println("<h2>" + cookies[i].getName() + ":"
+ cookies[i].getValue() + "</h2>");
}
}
}
} else if ("add".equals(option)) {
//创建Cookie对象
Cookie cookie = new Cookie("cool", "yeah!");
//设置生命周期以秒为单位
cookie.setMaxAge(20);
//添加Cookie
response.addCookie(cookie);
}
... ... ...
该Servlet对应的url-pattern为/testCookie
当浏览器请求地址“.../tst/testCookie?option=add”时,该Servlet创建一个Cookie对象,存储的键-值对为“cool”-“yeah”。通过response的addCookie方法将该Cookie信息添加到相应信息中。需要注意的是cookie的setMaxAge方法用于设置该cookie生命周期,单位是秒,如果过了这个期间,Cookie将失效。setMaxAge方法的参数如果为负值则表示该Cookie将在浏览器关闭时过期,如果参数为0则表示立刻删除该Cookie。访问该地址,对应的请求和响应的HTTP信息为:
请求:
GET /tst/testCookie?option=add HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, **
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)
Host: 192.168.5.100:8080
Connection: Keep-Alive
Cookie: cool=yeah!
响应:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 21
Date: Sun, 29 Jun 2008 06:15:26 GMT
<h2>cool:yeah!</h2>
注意,请求协议头中用于携带cookie信息的格式。
Cookie可以用于保持用户的会话状态,但Cookie信息保存在客户端,存在较大的安全隐患,且一般浏览器对Cookie的数目及数据大小有严格的限制。在Web应用中,一般情况下通过HttpSession对象保持会话状态。
二、Session
Session对象的原理在于,服务器可以为客户端创建并维护一个所谓的Session对象,用于存放数据。在创建Session对象的同时,服务器将会为该Session对象产生一个唯一编号,这个编号称之为SessionID,服务器以Cookie的方式将SessionID存放在客户端。当浏览器再次访问该服务器时,会将SessionID作为Cookie信息带到服务器,服务器可以通过该SessionID检索到以前的Session对象,并对其进行访问。需要注意的是,此时的Cookie中仅仅保存了一个SessionID,而相对较多的会话数据保存在服务器端对应的Session对象中,由服务器来统一维护,这样一定程度保证了会话数据安全性,但增加了服务器端的内存开销。
存放在客户端的用于保存SessionID的Cookie会在浏览器关闭时清除。我们把用户打开一个浏览器访问某个应用开始,到关闭浏览器为止交互过程称为一个“会话”。在一个“会话”过程中,可能会向同一个应用发出了多次请求,这些请求将共享一个Session对象,因为这些请求携带了相同的SessionID信息。
1. Session工作原理
下面的Servlet用来演示Session的工作原理:
... ... ...
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String option = request.getParameter("option");
if ("create".equals(option)) {
//获得HttpSession对象
HttpSession session = request.getSession();
//设置Session对象的最长不活动间隔
session.setMaxInactiveInterval(30);
//获取Session中的数据
List list = (List) session.getAttribute("list");
if (list == null) {
list = new ArrayList();
list.add("hey");
//向Session中添加数据
session.setAttribute("list", list);
} else {
list.add("hey");
}
out.println(list);
}else if ("invalidate".equals(option)) {
HttpSession session = request.getSession(false);
if (session != null) {
//使Session对象失效
session.invalidate();
}
}
... ... ...
该Servlet的url-pattern为/testSession。
当浏览器请求地址“.../tst/testSession?option=create”时,Servlet调用request的getSession方法获得Session对象,如果此时服务器端存在与请求信息中SessionID(作为Cookie信息携带)对应的Session对象,则返回这个Session对象,否则将会创建一个新的Session对象并将其产生的SessionID以Cookie的形式通过响应信息送回。注意,Session对象的setMaxInactiveInterval方法用于设置最长不活动间隔,单位是秒,如果出现在这个的时间段内Session对象没有被存取,则该Session对象将会失效。通常为了保证服务器的性能和出于安全性考虑,这个值要妥善的设置(Tomcat针对Session的MaxInactiveInterval会有默认的设置)。若setMaxInactiveInterval设置为负值,则表示该Session永不过期。另外,Session对象分别通过setAttribute和getAttribute方法存取数据,数据以“名称-对象”对的形式存放。该请求对应的请求和响应的HTTP信息为:
请求:
GET /tst/testSession?option=create HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, **
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)
Host: 192.168.5.100:8080
Connection: Keep-Alive
Cookie: JSESSIONID=C69B3053C575ECC8C7FCAF7D189A4FD1
响应
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 12
Date: Sun, 29 Jun 2008 07:20:41 GMT
[hey, hey]
注意:请求信息中携带的SessionID值与上一次相应的SessionID之一致。另外响应输出的HTML文本中有两个“hey”,这是因为这次请求Servlet往存放在Session中的list对象中又放置了一个String对象。
当浏览器请求“.../tst/testSession?option=invalidate”时,Servlet会调用Session对象的invalidate方法用于使该Session对象失效。需要注意的是,此时获取Session对象的方法为重载的getSession(boolean b)其中boolean类型的参数表示当前请求没有和服务器端的某个Session对象关联时是创建新的Session(参数为true时)还是返回null(参数为false时)。
[/size]
一、Cookie
Cookie的含义是“服务器送给浏览器的甜点”,即服务器在响应请求时可以将一些数据以“键-值”对的形式通过响应信息保存在客户端。当浏览器再次访问相同的应用时,会将原先的Cookie通过请求信息带到服务器端。
下面的Servlet展示了Cookie的功能。
... ... ...
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String option = request.getParameter("option");
if ("show".equals(option)) {
//获得请求信息中的Cookie数据
Cookie[] cookies = request.getCookies();
if (cookies != null) {
//找出名称(键)为“cool”的Cookie
for (int i = 0; i < cookies.length; i++) {
if ("cool".equals(cookies[i].getName())) {
out.println("<h2>" + cookies[i].getName() + ":"
+ cookies[i].getValue() + "</h2>");
}
}
}
} else if ("add".equals(option)) {
//创建Cookie对象
Cookie cookie = new Cookie("cool", "yeah!");
//设置生命周期以秒为单位
cookie.setMaxAge(20);
//添加Cookie
response.addCookie(cookie);
}
... ... ...
该Servlet对应的url-pattern为/testCookie
当浏览器请求地址“.../tst/testCookie?option=add”时,该Servlet创建一个Cookie对象,存储的键-值对为“cool”-“yeah”。通过response的addCookie方法将该Cookie信息添加到相应信息中。需要注意的是cookie的setMaxAge方法用于设置该cookie生命周期,单位是秒,如果过了这个期间,Cookie将失效。setMaxAge方法的参数如果为负值则表示该Cookie将在浏览器关闭时过期,如果参数为0则表示立刻删除该Cookie。访问该地址,对应的请求和响应的HTTP信息为:
请求:
GET /tst/testCookie?option=add HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, **
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)
Host: 192.168.5.100:8080
Connection: Keep-Alive
Cookie: cool=yeah!
响应:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 21
Date: Sun, 29 Jun 2008 06:15:26 GMT
<h2>cool:yeah!</h2>
注意,请求协议头中用于携带cookie信息的格式。
Cookie可以用于保持用户的会话状态,但Cookie信息保存在客户端,存在较大的安全隐患,且一般浏览器对Cookie的数目及数据大小有严格的限制。在Web应用中,一般情况下通过HttpSession对象保持会话状态。
二、Session
Session对象的原理在于,服务器可以为客户端创建并维护一个所谓的Session对象,用于存放数据。在创建Session对象的同时,服务器将会为该Session对象产生一个唯一编号,这个编号称之为SessionID,服务器以Cookie的方式将SessionID存放在客户端。当浏览器再次访问该服务器时,会将SessionID作为Cookie信息带到服务器,服务器可以通过该SessionID检索到以前的Session对象,并对其进行访问。需要注意的是,此时的Cookie中仅仅保存了一个SessionID,而相对较多的会话数据保存在服务器端对应的Session对象中,由服务器来统一维护,这样一定程度保证了会话数据安全性,但增加了服务器端的内存开销。
存放在客户端的用于保存SessionID的Cookie会在浏览器关闭时清除。我们把用户打开一个浏览器访问某个应用开始,到关闭浏览器为止交互过程称为一个“会话”。在一个“会话”过程中,可能会向同一个应用发出了多次请求,这些请求将共享一个Session对象,因为这些请求携带了相同的SessionID信息。
1. Session工作原理
下面的Servlet用来演示Session的工作原理:
... ... ...
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String option = request.getParameter("option");
if ("create".equals(option)) {
//获得HttpSession对象
HttpSession session = request.getSession();
//设置Session对象的最长不活动间隔
session.setMaxInactiveInterval(30);
//获取Session中的数据
List list = (List) session.getAttribute("list");
if (list == null) {
list = new ArrayList();
list.add("hey");
//向Session中添加数据
session.setAttribute("list", list);
} else {
list.add("hey");
}
out.println(list);
}else if ("invalidate".equals(option)) {
HttpSession session = request.getSession(false);
if (session != null) {
//使Session对象失效
session.invalidate();
}
}
... ... ...
该Servlet的url-pattern为/testSession。
当浏览器请求地址“.../tst/testSession?option=create”时,Servlet调用request的getSession方法获得Session对象,如果此时服务器端存在与请求信息中SessionID(作为Cookie信息携带)对应的Session对象,则返回这个Session对象,否则将会创建一个新的Session对象并将其产生的SessionID以Cookie的形式通过响应信息送回。注意,Session对象的setMaxInactiveInterval方法用于设置最长不活动间隔,单位是秒,如果出现在这个的时间段内Session对象没有被存取,则该Session对象将会失效。通常为了保证服务器的性能和出于安全性考虑,这个值要妥善的设置(Tomcat针对Session的MaxInactiveInterval会有默认的设置)。若setMaxInactiveInterval设置为负值,则表示该Session永不过期。另外,Session对象分别通过setAttribute和getAttribute方法存取数据,数据以“名称-对象”对的形式存放。该请求对应的请求和响应的HTTP信息为:
请求:
GET /tst/testSession?option=create HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, **
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)
Host: 192.168.5.100:8080
Connection: Keep-Alive
Cookie: JSESSIONID=C69B3053C575ECC8C7FCAF7D189A4FD1
响应
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 12
Date: Sun, 29 Jun 2008 07:20:41 GMT
[hey, hey]
注意:请求信息中携带的SessionID值与上一次相应的SessionID之一致。另外响应输出的HTML文本中有两个“hey”,这是因为这次请求Servlet往存放在Session中的list对象中又放置了一个String对象。
当浏览器请求“.../tst/testSession?option=invalidate”时,Servlet会调用Session对象的invalidate方法用于使该Session对象失效。需要注意的是,此时获取Session对象的方法为重载的getSession(boolean b)其中boolean类型的参数表示当前请求没有和服务器端的某个Session对象关联时是创建新的Session(参数为true时)还是返回null(参数为false时)。
[/size]