1、简介
前面章节说了客户端浏览器和web服务器之间,一次请求对应一次响应。而一次会话包含多次请求和响应,直到一方断开为止。会话的作用是在多次请求之间共享数据。
Cookie是客户端会话技术,Session是服务器端会话技术。
2、Cookie
Cookie会话技术的特点是数据保存在客户端。
2.1 快速入门
使用步骤如下:
1. 创建Cookie对象,绑定数据:new Cookie(String name, String value)
2. 发送Cookie对象:response.addCookie(Cookie cookie)
3. 获取Cookie,拿到数据:Cookie[] request.getCookies()
// CookieDemo01.java
@WebServlet("/CookieDemo01")
public class CookieDemo01 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie c = new Cookie("msg","hellocookie");
response.addCookie(c);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
// CookieDemo02.java
@WebServlet("/CookieDemo02")
public class CookieDemo02 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
String name = cookie.getName();
String value = cookie.getValue();
System.out.println(name + " : " + value);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
----- 分割线 -----
浏览器先访问:http://localhost:8080/CookieDemo01
然后访问:http://localhost:8080/CookieDemo02
即可在IDEA控制台看到以下输出:
goSessionid : Wncvi0tyJyz2w_DjxEb271CUCnglx8VA3QGHxFBj7jE%3D
JSESSIONID : 8ED975A0AD0F4F5CD065E595565C3457
msg : hellocookie
2.2 原理和细节
Cookie是基于响应头set-cookie和请求头cookie实现的,即在响应头中增加Cookie: 键=值
。
一次可以发送多个cookie,只需要response多次调用addCookie
方法即可。
默认情况下,浏览器关闭后,即会话结束,Cookie数据被销毁,可以通过setMaxAge(int seconds)
方法把cookie写到硬盘中,指定存活时间,时间过后自动失效。seconds为正数表示存活时间,负数是默认值,零表示删除cookie信息。
Tomcat 8之后可以存储中文,在之前只能使用URL编码来存储中文。但是还是建议使用URL编码,因为有些特殊字符还是不支持。
当一个Tomcat服务器存在多个web项目,可以通过setPath(String path)
来设置数据共享范围,只需要设置path为/
即可。
当存在多个不同的tomcat服务器时,只需要通过setDomain(String path)
方法来设置一级域名相同,就可以在多个服务器之间共享cookie,如:setDomain(".baidu.com")
,则tieba.baidu.com和news.baidu.com中cookie可以共享。
2.3 特点和作用
Cookie数据存储在客户端浏览器中,浏览器对于单个cookie 的大小有限制(4kb) 以及对同一个域名下的总cookie数量也有限制(20个)。
cookie一般用于存出少量的不太敏感的数据,在不登录的情况下,完成服务器对客户端的身份识别。
3、Session
Session是服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。我们使用的是HttpSession对象。
3.1 快速入门
1. 获取HttpSession对象:HttpSession session = request.getSession();
2. 使用HttpSession对象:
Object getAttribute(String name)
void setAttribute(String name, Object value)
void removeAttribute(String name)
// SessionDemo01.java
@WebServlet("/SessionDemo01")
public class SessionDemo01 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.setAttribute("message","helloSession");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
// SessionDemo02.java
@WebServlet("/SessionDemo02")
public class SessionDemo02 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
Object message = session.getAttribute("message");
System.out.println("message:" + message);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
----- 分割线 -----
浏览器先访问:http://localhost:8080/SessionDemo01
然后访问:http://localhost:8080/SessionDemo02
即可在IDEA控制台看到以下输出:
message:helloSession
3.2 原理和细节
Session的实现是依赖于Cookie的,Session首先在服务器内存中开辟一个区域用于存储Session数据,然后在返回的response中添加一个cookie保存Session的id,当客户端浏览器第二次访问服务器时,服务器通过request带来的cookie中的Session的id来找到对应的Session,实现会话数据共享。
当客户端和服务器任何一方关闭了,理论上会话就结束了,session也就销毁了。
当客户端关闭后,服务器不关闭,两次获取session在默认情况下就不是一个了,如果需要,可以通过自定义一个cookie来保存session的id,然后设置cookie的存活时间来间接保存session,因为session的内容是保存在服务器的内存上的,服务器不关闭且该数据有引用,就不会被销毁。
Cookie c = new Cookie("JSESSIONID",session.getId());
c.setMaxAge(60*60);
response.addCookie(c);
当客户端不关闭,而服务器重启了,两次获取的session默认肯定也不是同一个了。如果需要,可以让session完成钝化和活化,钝化就是在服务器正常关闭之前,将session对象系列化到硬盘上,活化就是在服务器启动后,将session文件转化为内存中的session对象。然后只要sessionID直到,那么session的内容就可以重新读出来,钝化和活化Tomcat会自动执行。
默认情况下,session在服务器关闭后就销毁了;或者调用session对象的invalidate()
方法也可以销毁;session默认失效时间是30分钟。