目录
什么是会话
http是无状态的协议,每次请求之间是独立的。客户端请求访问 web 服务器时,服务器会打开一个会话响应,但是当你多次请求访问服务器,服务器并不知道每次都是你来请求访问,服务器也不会自动维护客户的上下文信息,所以服务器每次都会打开新的会话,每次请求都是独立的。
如果在淘宝上购物时,访问一个物品页面并将其加入到购物车,这是一次请求;然后又访问另一个物品页面并将其加入到购物车,这是一次新请求;然后到购物车界面去结算,这又是一次新请求,此时这三个请求是独立的,不会共享数据,服务器也不知道是一个客户的操作,这样导致购物车中什么都没有。所以需要建立会话,用于识别这三次请求是否来自同一个客户并共享每次请求的数据,这样在购物车进行结算时,每次同一个客户请求加入到购物车的物品信息都会被共享到这次请求中。
会话:从打开浏览器
开始访问到关闭浏览器或服务器
这一过程,就是一次会话。一次会话中可以进行多次请求响应。
会话技术是用来在一次会话中的多次请求间共享数据。
会话技术可分为两种:Cookie 和 Session。
Cookie(客户端会话技术)
Cookie 原理
Cookie 客户端会话技术:是将数据储存在客户端。
当客户端第一次请求访问服务器时,会建立与服务端的一次会话,并会生成一个Cookie,通过 Response 响应返回给客户端,并将 Cookie 保存到客户端本地。当客户端再次请求访问服务端时,Cookie 会跟着 Request 请求一起到服务器,服务器会先查找 Cookie 中记录的信息,返回相应的信息给用户端。
Cookie 是以键值对(Key:Value)的形式存储在本地硬盘,用户可以手动删除 Cookie 信息或者服务端通过 cookie.setMaxAge(int seconds) 设置 Cookie 在客户端的持久化时间,当过了持久化时间后,浏览器将自动删除该 Cookie 信息(如果不设置持久化时间,默认是在浏览器关闭后销毁 Cookie 信息)。
使用步骤:
1、创建Cookie对象,绑定数据。服务器端创建。
- new Cookie(String name, String value)
2、发送Cookie对象。将Cookie加入到response响应中,会随着响应自动发送到客户端。
- response.addCookie(Cookie cookie)
3、 获取Cookie,拿到数据。request会自动携带Cookie去请求服务器。
- Cookie[] request.getCookies()
代码示例:
第一次请求的资源
@WebServlet("/demoCookie1")
public class DemoCookie1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 创建Cookie
Cookie cookie = new Cookie("name", "qgl");
// 设置Cookie存活时间,cookie.setMaxAge(30);
// Cookie添加到响应消息中,并发送
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
第二次请求的资源
@WebServlet("/demoCookie2")
public class DemoCookie2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 从请求消息中获取Cookie
Cookie[] cookies = req.getCookies();
if(cookies != null){
for(Cookie ck : cookies){
System.out.println(ck);
System.out.println(ck.getName());
System.out.println(ck.getValue());
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
第一次请求访问 http://localhost:8080/demoCookie1 并建立会话,可以看到在响应头中有 set-cookie:name = qgl,这是第一次请求建立会话创建 cookie 保存到客户端中。此时请求头中没有对应的 cookie:name = qgl 信息。
会话中第二次请求访问 http://localhost:8080/demoCookie2,可以看到在响应头中没有 set-cookie:name = qgl,第二次请求的请求头中有 cookie:name = qgl,说明一次会话中的多次请求,并且每次请求信息中会携带第一次请求创建的 cookie 信息。
cookie在浏览器中保存时间:
- 默认情况下,当浏览器关闭后,Cookie数据被销毁
- 持久化存储:调用Cookie类中的方法
setMaxAge(int seconds)
- 正数:将Cookie数据写到硬盘的文件中。持久化存储。并指定cookie存活时间,时间到后,cookie文件自动失效。
- 负数:默认值
- 零:删除cookie信息
cookie 作用域
-
在一个web项目,所有资源可以共享cookie。
-
假设在一个 tomcat 服务器中,部署了多个 web 项目,那么在这些web项目中cookie能不能共享?
-
默认情况下cookie不能共享
-
setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录。如果多个项目要共享,则可以将path设置为 “/”。path为虚拟目录。
-
-
不同的 tomcat 服务器间 cookie 共享问题?
setDomain(String path):如果设置一级域名相同,那么多个服务器之间 cookie 可以共享。
如:setDomain(".baidu.com"),那么 tieba.baidu.com 和 news.baidu.com
中cookie可以共享。baidu.com为一级域名。
Cookie的特点和作用:
-
cookie存储数据在客户端浏览器
-
浏览器对于单个cookie 的大小有限制(4kb) 以及对同一个域名下的总cookie数量也有限制(20个)
-
作用:
- cookie一般用于存储少量的不太敏感的数据。
- 在不登录的情况下,完成服务器对客户端的身份识别。
Session(服务端会话技术)
Session 原理:
Session 服务端会话技术:是将数据储存在服务器端。
在一次会话的多次请求间共享数据,将数据保存在服务器端的 HttpSession 对象中。
Session对象是由服务器自动创建的与用户请求相关的对象
。服务器为每个用户都生成一个Session对象,用于保存该用户的信息,跟踪用户的操作状态。简单的说,Session是一种把会话数据保存到服务器端的技术。
1、当浏览器第一次发送请求时,服务器自动生成了一个Session和一个Session ID用来唯一标识这个Session,并将其通过响应的 Cookie 发送到浏览器本地保存 Session ID。
2、当浏览器第二次发送请求,会将保存在 Cookie 中的 Session ID 放在请求头中一并发送到服务器端,服务器从请求中提取出 Session ID,并和保存的所有 Session ID 进行对比,找到这个用户对应的 Session。
使用 Session:
- 获取HttpSession对象:
HttpSession session = request.getSession();- 使用HttpSession对象:
Object getAttribute(String name)
void setAttribute(String name, Object value)
void removeAttribute(String name)
代码示例:
第一次请求的资源
@WebServlet("/demoSession1")
public class DemoSession1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.setAttribute("name","qgl");
System.out.println(session);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
第二次请求的资源
@WebServlet("/demoSession2")
public class DemoSession2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
Object name = session.getAttribute("name");
System.out.println(name);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
第一次请求访问 http://localhost:8080/demoSession1 并建立会话,可以看到在响应头中有 Set-Cookie: JSESSIONID=8C051535023AE5E7E4C4ADEEECE2618D,这是第一次请求建立会话,服务器会创建 HttpSession 对象并通过 Cookie 保存有关信息到客户端中。此时请求头中没有对应的信息。
会话中第二次请求访问 http://localhost:8080/demoSession2,可以看到请求头中有 Cookie:JSESSIONID=8C051535023AE5E7E4C4ADEEECE2618D,说明一次会话中的多次请求,并且每次请求信息中会携带第一次请求创建的带有Session 的 cookie 信息。
Session 作用域
-
当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
-
默认情况下。不是。
-
如果需要相同,则可以创建 Cookie,键为 JSESSIONID,设置存活时间,让 cookie持久化保存。
Cookie c = new Cookie("JSESSIONID",session.getId()); c.setMaxAge(60*60); response.addCookie(c);
-
-
客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
-
不是同一个,但是要确保数据不丢失。tomcat自动完成以下工作
1、session 的钝化:
- 在服务器正常关闭之前,将 session 对象序列化到硬盘上
2、session 的活化:
- 在服务器启动后,将 session 文件转化为内存中的 session 对象即可。
- 在服务器正常关闭之前,将 session 对象序列化到硬盘上
-
-
session什么时候被销毁?
-
服务器关闭
-
session对象调用invalidate() 。
-
session默认失效时间 30分钟
在tomcat配置文件中修改配置,设置时间。
<session-config> <session-timeout>30</session-timeout> </session-config>
-
session的特点:
- session用于存储一次会话的多次请求的数据,存在服务器端
- session可以存储任意类型,任意大小的数据
session与Cookie的区别:
- session存储数据在服务器端,Cookie在客户端
- session没有数据大小限制,Cookie有
- session数据安全,Cookie相对于不安全