会话技术
一、会话-简介
讲解
1. 什么是会话
- 会话开始:客户端输入网址并回车,和服务端建立连接,会话开始
- 会话过程:客户端和服务端之间可以有 多次请求和响应
- 会话结束:关闭浏览器,会话结束
2. 什么是会话技术
- 用于保存会话过程中的一些数据的技术。
- 特点:
- 不同会话之间,数据存储是互不干扰,相互独立
- 同一会话内部,多次请求之间,数据存储要能够共享
3. 有哪些会话技术
- Cookie:客户端的会话技术,把会话数据存储到客户端
- 优点:服务器压力小
- 缺点:安全性低,只能保存字符串
- session:服务端的会话技术,把会话数据存储到服务端
- 优点:安全性高,可以存储任意类型数据(Object)
- 缺点:服务器压力大
- 实际使用时,如何选择用哪种会话技术:
- 如果安全性要求高,就要使用session技术;否则可以使用Cookie技术
小结
- 了解什么是会话
- 会话开始:客户端输入地址并回车,和服务端建立连接–会话开始
- 会话结束:关闭浏览器,会话结束
- 会话过程:客户端和服务端之间,可以有任意多次请求和响应
- 了解什么是会话技术
- 存储 会话过程中的一些数据 的技术,有Cookie和session
- 理解会话技术的特点【重点】
- 不同会话之间,数据是相互独立,互不干扰的
- 同一会话内部,多次请求之间,数据是共享的
- Cookie:
- 服务器压力小; 安全性低,只能存储字符串
- session:依赖于Cookie技术
- 服务器压力大; 安全性高,可以存储任意类型数据
二、会话-Cookie
1. Cookie的使用过程【重点】
讲解
Cookie的使用过程【重点】
- 客户端:请求到服务端
- 服务端:创建Cookie,把数据放到Cookie里,再发送给客户端
- 客户端:
- 浏览器会自动接收并保存Cookie数据
- 再发请求时,会自动把Cookie数据携带到服务端
- 服务端:接收客户端携带的Cookie数据
Cookie的主要API
- 创建Cookie:
Cookie cookie = new Cookie(String name, String value)
- 发送Cookie:
response.addCookie(cookie)
- 接收Cookie :
request.getCookies()
注意事项
- 原则上:
- 浏览器最多存储300个Cookie(实际上,不同浏览器不同)
- 每个服务端最多给一个浏览器20个Cookie(实际上,不同浏览器不同)
- 每个Cookie限制大小4KB
使用示例
- 创建并发送Cookie
@WebServlet(urlPatterns="/create", name="Demo01CreateCookieServlet")
public class Demo01CreateCookieServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建Cookie
Cookie cookie = new Cookie("username", "zhangsan");
//发送Cookie到客户端 以响应头的方式,发送到客户端 Set-Cookie: username=zhangsan
response.addCookie(cookie);
Cookie cookie1 = new Cookie("age", "20");
response.addCookie(cookie1);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
- 接收客户端携带的Cookie
@WebServlet(urlPatterns="/recieve", name="Demo02RecieveCookieServlet")
public class Demo02RecieveCookieServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//接收客户端携带的Cookie。以请求头的形式发送到服务端 Cookie: username=zhangsan
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);
}
}
- 客户端浏览器测试:
- 先访问
Demo01CreateCookieServlet
:Servlet会生成Cookie数据,随着HTTP响应返回客户端浏览器 - 再访问
Demo02RecieveCookieServlet
:浏览器发HTTP请求时,会自动把cookie数据携带到服务端- 服务端可以接收到Cookie数据
- 先访问
小结
- Cookie使用的基本过程:
- 客户端:
- 请求到服务端
- 服务端:
- 创建Cookie:
new Cookie(String name, String value)
- 把Cookie返回客户端:
response.addCookie(cookie)
- 创建Cookie:
- 客户端:
- 自动接收并保存Cookie数据
- 再次请求到服务端,会自动把Cookie数据携带到服务端
- 服务端:
- 接收客户端携带的Cookie:
request.getCookies()
- 接收客户端携带的Cookie:
- 客户端:
2. Cookie的API详解
2.1 Cookie对象的有效期
讲解
-
什么是有效期:Cookie的存活时间
-
Cookie的默认有效期:一次会话期间
- Cookie默认保存在浏览器内存里,浏览器关闭,内存清空
-
设置Cookie的有效期:
cookie.setMaxAge(int seconds)
- 在到期之前,无论浏览器是否关闭,Cookie始终是有效的(活着的)
- 在到期之后,Cookie会自动失效
-
是在磁盘文件上保存的
- Cookie过期会自动失效
- 强制清除浏览器缓存:快捷键 ctrl + shift + delete
小结
- 了解什么是Cookie的有效期:Cookie的存活时间
- 能说出Cookie的默认有效期:一次会话期间(浏览器关闭,Cookie就被清除了)
- 能设置Cookie的有效期:
cookie.setMaxAge(int seconds)
- 设置了有效期后,在到达有效期之前,Cookie始终有效,无论浏览器是否关闭
2.3 Cookie对象的有效范围(路径)
讲解
-
什么是有效范围:
- 只有在访问有效范围内的资源时,才会携带Cookie到服务端
客户端在访问服务端资源时,浏览器具备:自动把Cookie携带到服务端的能力 但是:并非访问服务端任意资源时,都会把Cookie携带到服务端。 只有:当客户端访问有效范围内的资源时,才会把Cookie携带到服务端
-
Cookie的默认有效范围:生成这个Cookie的资源,所在的目录
- 生成Cookie的资源是:
/day11/aa/create
- 这个Cookie的有效范围:
/day11/aa
- 生成Cookie的资源是:
-
设置Cookie的有效范围(设置Cookie的路径):
cookie.setPath(String path)
注意:路径的值,不需要写ip和端口,直接写
/项目路径/....
-
生成Cookie的资源是:
/day11/aa/create
,那么:-
默认有效范围:
/day11/aa
-
如果设置了有效范围是:
/day11
,就会覆盖默认的有效范围
-
-
这个Cookie的有效范围是:
/day11
-
如果访问一个资源:
http://localhost/day11/recieve
,在有效范围内,会携带到服务端 -
如果访问一个资源:
http://localhost/day11/aa/recieve
,在有效范围内,会携带到服务端
-
小结
-
了解什么是Cookie的有效范围(Cookie的路径)
- 当浏览器访问有效范围内的资源时,才会把Cookie携带到服务端
-
能说出Cookie的默认有效范围
- 生成Cookie的资源,所在的目录。
生成Cookie的资源是:http://localhost:80/day09/aa/createCookie 这个Cookie有效范围:http://localhost:80/day09/aa 当客户端访问: http://localhost:80/day09/recieveCookie,不在有效范围里,不携带 http://localhost:80/day09/aa/recieveCookie,在有效范围里,会携带到服务端
-
能设置Cookie的有效范围:
cookie.setPath(String path)
生成Cookie的资源是:http://localhost:80/day09/aa/createCookie 设置Cookie有效范围:http://localhost:80/day09 这个Cookie有效范围:http://localhost:80/day09 当客户端访问: http://localhost:80/day09/recieveCookie,在有效范围里,会携带到服务端 http://localhost:80/day09/aa/recieveCookie,在有效范围里,会携带到服务端
3. 接收Cookie
讲解
- API:
Cookie[] cookies = request.getCookies()
- Cookie对象的方法:
方法 | 参数 | 返回值 | 说明 |
---|---|---|---|
getName() | 无参 | String | Cookie的名称 |
getValue() | 无参 | String | Cookie的值 |
Cookie里其它数据是获取不到的,只能获取name和value
小结
4. 删除Cookie
目标
- 能够删除客户端的Cookie
讲解
- 服务端不能直接删除客户端的Cookie数据,只能间接删除:
- 创建一个同name、同path的Cookie,设置有效期为0,然后发送到客户端,会覆盖掉原有的Cookie。
- 相当于:给客户端发送一个同归于尽的Cookie
- 示例
//要求:删除掉客户端的Cookie---名称为username,有效范围是默认的 /day11
//做法:创建一个名称为username、有效范围(路径)为/day11的Cookie。有效期设置为0
//把这个Cookie发送到客户端 和 客户端的username(/day11)的Cookie同归于尽
Cookie cookie = new Cookie("username", "");
cookie.setMaxAge(0);
cookie.setPath(request.getContextPath());
response.addCookie(cookie);
小结
5. 练习:上次访问时间
目标
- 不登录状态下,当用户访问
/visit
时,在浏览器上显示上次访问的时间
分析
实现
@WebServlet(urlPatterns="/visit")
public class VisitServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.记录本次访问时间,放到Cookie里。在响应时返回给客户端,让浏览器保存起来
Cookie cookie = new Cookie("visitTime", System.currentTimeMillis() + "");
cookie.setMaxAge(30*24*60*60);
response.addCookie(cookie);
//2.获取客户端携带过来的Cookie:上次访问时间,显示到页面上
String lastVisit = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie c : cookies) {
if ("visitTime".equals(c.getName())) {
lastVisit = c.getValue();
break;
}
}
}
response.setContentType("text/html;charset=utf-8");
if (lastVisit == null || "".equals(lastVisit)) {
response.getWriter().print("你是第一次访问");
}else{
Date date = new Date(Long.parseLong(lastVisit));
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
response.getWriter().print("你上次访问时间是:" + format.format(date));
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
小结
三、会话-session
1. session的使用过程【重点】
讲解
- 客户端:发送请求到服务端
- 服务端:
- 得到一个session对象:
request.getSession()
- 把session的id,放到Cookie里,发送到客户端(由Tomcat做)
- 得到一个session对象:
- 客户端:
- 得到并保存Cookie:session的id(由浏览器做)
- 再发请求到服务端:把Cookie(session的id)携带到服务端(由浏览器做)
- 服务端:
- 接收客户端携带的Cookie(session的id):(由Tomcat做)
- 根据session的id,得到session对象:
request.getSession()
小结
2. 获取session对象
讲解
-
获取session的API:
HttpSession session = request.getSession()
-
什么时候是获取旧的session对象:
- 客户端有JSESSIONID,并且 服务端有对应的session对象
-
什么时候是创建新的session对象:
- 客户端没有JSESSIONID, 或者 服务端没有对应的session对象
小结
3. session存取数据(是一个域对象)
目标
- 能说出session对象何时会创建
- 能说出session对象何时会销毁
讲解
-
session存取数据的方法
- 存数据:
setAttribute(String name, Object value)
- 取数据:
getAttribute(String name)
- 删数据:
removeAttribute(String name)
- 存数据:
-
session什么时候会创建?一次会话开始
- 客户端没有JSESSIONID, 或者 服务端没有对应的session对象
-
session什么时候会销毁?一次会话结束
-
服务器非正常关闭,sessoin销毁。
- 正常关闭时,Tomcat会把session对象序列化保存到磁盘文件上;
- 重启Tomcat时,会读取文件反序列化恢复成session对象
-
会话超时,自动销毁:默认30分钟
-
访问一个web应用,之后长时间不再访问,session会等待30分钟之后才消失
-
从最后一次访问算30分钟
-
修改默认的会话超时时间,修改
WEB-INF/web.xml
<session-config> <session-timeout>超时时间,单位是分钟</session-timeout> </session-config>
-
-
手动销毁:
session.invalidate()
-
-
session的作用范围是?一次会话期间
-
只要还能找到原有的session对象,里边的数据就能够获取(仍然可以共享的)
-
什么情况可能会获取不到session里的数据?
- 客户端的JSESSIONID丢了:
- 浏览器清除缓存了
- 浏览器关闭重启了
- 浏览器是第一次访问
- 服务端的session对象消失了:
- 服务器非正常关闭了
- 会话超时,session销毁了
- session被手动销毁了
- 客户端的JSESSIONID丢了:
-
小结
拓展:域对象小结【面试题】
-
域对象:由Servlet规范提供的,可以临时存储数据的对象。域对象里的数据,在其作用范围里,可以共享
-
不同域对象,存取数据的方法相同:
- 存数据:
setAttribute(String name, Object value)
- 取数据:
getAttribute(String name)
- 删数据:
removeAttribute(String name)
- 存数据:
-
不同域对象,作用范围是不同的:
-
ServletContext:
- 何时创建:服务器启动时
- 何时销毁:服务器关闭时
- 作用范围:整个web应用
所有会话 所有请求 访问一个web应用的 所有资源:同一个ServletContext
-
session:
-
何时创建:一次会话开始。
客户端没有JSESSIONID,或者 服务端没有对应的session对象
-
何时销毁:一次会话结束
服务器非正常关闭,会话超时,手动销毁:session对象会销毁掉
-
作用范围:一次会话期间
一个会话内所有请求 访问一个web应用的 所有资源:同一个session
-
-
request:
- 何时创建:一次请求开始
- 何时销毁:一次请求结束
- 作用范围:一次请求期间
一个会话内 一次请求 访问一个web应用的 一个资源:同一个request域
-
pageContext:
- 何时创建:一个JSP被访问到时
- 何时销毁:一个JSP被访问完成
- 作用范围:一个JSP里
一个会话内 一次请求 访问一个web应用的 一个JSP:同一个pageContext
-