好记性不如烂笔头
会话技术
- 会话:一次会话包含多个请求和响应.
- 一次会话: 浏览器第一次给服务器发送请求时,会话建立,直到有一方断开连接为止. (浏览器关闭 || 服务器崩溃 等)
- 功能:在一次会话的范围内的多次请求间共享数据
- 方式:
- Cookie:客户端会话技术
- Session:服务器端会话技术
Cookie
-
概念:客户端会话技术,将数据保存在客户端浏览器中
-
快速入门:
-
创建Cookie对象,绑定数据
- new Cookie(String name, String value) 构造具有指定名称和值的cookie。
Cookie cookie = new Cookie("msg", "helloCookie");
-
发送Cookie对象
- response.addCookie(Cookie cookie) 将指定的cookie添加到响应中。
response.addCookie(cookie);
-
获取Cookie对象,拿到数据
- Cookie[] getCookies() 返回一个数组,其中包含客户端使用此请求发送的所有 Cookie对象。
Cookie[] cookies = request.getCookies(); //获取数据 for (Cookie cookie : cookies) { String name = cookie.getName();//通过cookie获取到其其存储数据的name值 //获取其value String value = cookie.getValue(); System.out.println(name+":"+value); }
//Cookie cookie = new Cookie("msg", "helloCookie");前 JSESSIONID:41C862EEDE5396BF7290143EC3D82283 Idea-3ca48729:f25a110b-be41-4507-bd9b-4c443b8232b4 //Cookie cookie = new Cookie("msg", "helloCookie");执行后 JSESSIONID:41C862EEDE5396BF7290143EC3D82283 msg:helloCookie Idea-3ca48729:f25a110b-be41-4507-bd9b-4c443b8232b4
- 结论:当浏览器关闭后,cookie就失效了,当然其中存储的数据也就失效了
-
-
实现原理:
- 基于第一次请求的响应头(set-cookie)和后续请求的请求头(cookie)实现.
-
使用cookie时的细节问题:
1.发送cookie时一次可不可以发送多个cookie?
-
可以
-
可以创建多个cookie对象,使用response调用多次addCookie方法去保存
-
如果多次存储的数据name值一致, 后续存储的值会将前面的进行覆盖处理
2.cookie在浏览器中可以保存多久呢?
-
-
默认情况下,当浏览器关闭时,cookie数据将被销毁
-
cookie持久化存储:
void setMaxAge(int expiry) 设置此Cookie的最大年龄(以秒为单位)
Cookie cookie = new Cookie("name", "helloCookie");
//设置其存活周期:
//cookie.setMaxAge(-1); //默认值
//cookie.setMaxAge(0);//删除cookie
cookie.setMaxAge(40); //将cookie持久化到硬盘 40s后自动删除cookie文件
response.addCookie(cookie);
-
参数:
正数:正值表示cookie将在经过许多秒后过期。 请注意,该值是cookie过期时的最大年龄,而不是cookie的当前年龄。
0:零值会导致cookie被删除。 (删除cookie信息)
负数(默认值):负值表示cookie不会持久存储,并在Web浏览器退出时被删除。
-
cookie共享问题?
//设置path路径 让当前服务器下部署的所有项目共享该cookie信息 cookie.setPath("/");
假设在一个tomcat服务器中,部署了多个web项目,那么请问这些web项目中cookie的值是否可以共享呢?
-
默认情况下cookie不能共享
setPath(String path) //设置path路径"/" 让当前服务器下部署的所有项目共享该cookie信息
-
在不同的tomcat服务器中 cookie能否共享呢?
-
默认不可以
-
void setDomain(String domain) :如果设置两个服务器的一级域名相同,那么多个服务器之间cookie可以共享
-
setDomain(".baidu.com") 那么百度贴吧和百度百科的一级域名都为"baidu.com" 那么他们之间就可以进行cookie数据共享
https://tieba.baidu.com/ 百度贴吧
https://baike.baidu.com/ 百度百科
-
-
4. cookie是否可以存储中文?
-
tomcat 8 之前不能直接存储中文数据
需要将中文数据转码–>URL编码(%E3)
-
tomcat 8 及以上版本 支持中文数据 但不支持特殊字符(例如 空格 #$%&*) 建议使用URL编码存储 URL编码解析
- cookie的特点和作用
- 特点:
- cookie存储数据在客户端浏览器上
- 浏览器对于单个cookie的大小有限制(4kb) 以及对同一个域名下的总的cookie数量有限制(20)
- 作用:
- cookie一般用于存储少量的不太敏感的数据(不安全)
- 在不登录的情况下,cookie可以完成服务器对客户端的身份识别.
- 特点:
- 案例:如何让浏览器记住你上次登陆过.
- 需求:
- 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问
- 如果不是第一次访问 则提示:欢迎回来,您上次访问的时间为:yyyy-MM-dd HH:mm:ss
- 分析:
- 可以采用cookie实现该案例
- 在服务器的Servlet代码中判断是否有一个名字叫lastTime的cookie
- 有:不是第一次访问:
- 响应数据:欢迎回来,您上次访问的时间为:yyyy-MM-dd HH:mm:ss
- 写回cookie:将当前系统时间写入到cookie中,将之前时间覆盖掉
- 没有:是第一次访问:
- 响应数据:您好,欢迎您首次访问
- 写回cookie:将当前系统时间写入到cookie中
- 有:不是第一次访问:
- 需求:
@WebServlet("/cookieTest")
public class CookieTest extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.设置响应消息体的数据格式以及编码字符集
response.setContentType("text/html;charset=utf-8");
boolean flag = false; //设置是否有一个名字叫lastTime的cookie 默认 false 没有
//2.获取所有的cookie数据 遍历数组 看里面是否有一个叫lastTime的cookie
Cookie[] cookies = request.getCookies(); //2.1:获取所有的cookie数据
if (cookies != null && cookies.length>0){
for (Cookie cookie : cookies) { //2.2:遍历数组
String name = cookie.getName(); //2.3:获取每一个cookie的name值
if ("lastTime".equals(name)){ //2.4:看里面是否有一个叫lastTime的cookie
// 有 不是第一次访问
flag = true;
String lastValue = cookie.getValue(); //获取上一次访问的时间 用于在页面展示
String str_date = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date());
System.out.println("编码前的时间为:"+str_date);
str_date = URLEncoder.encode(str_date,"utf-8");
System.out.println("编码后的时间为:"+str_date);
cookie.setValue(str_date);
cookie.setMaxAge(60*60*24*30); //设置存活时间为一个月
response.addCookie(cookie);
System.out.println("解码前的上一次时间为:"+lastValue);
lastValue = URLDecoder.decode(lastValue,"utf-8");
System.out.println("解码后的上一次时间为:"+lastValue);
response.getWriter().write("<h1>欢迎回来,您上次登陆的时间为:"+lastValue+"</h1>");
break; //终止当前循环
}
}
}
// 第一次访问
if (cookies == null || cookies.length == 0 || flag == false){
String str_date = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date());
System.out.println("编码前的时间为:"+str_date);
str_date = URLEncoder.encode(str_date,"utf-8");
System.out.println("编码后的时间为:"+str_date);
Cookie cookie = new Cookie("lastTime", str_date);
cookie.setMaxAge(60*60*24*30); //设置存活时间为一个月
response.addCookie(cookie);
response.getWriter().write("<h1>您好,欢迎您首次访问!</h1>");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
Session
1.概念
服务器端会话技术,在一次会话的多次请求中共享数据, 将数据保存在服务器中的对象中(HttpSession)
2.快速入门
- 获取HttpSession对象:
- HttpSession session = request.getSession();
- 使用HttpSession对象:
- session.getAttribute("");
- session.setAttribute("","");
- session.removeAttribute("");
3.原理
- Session的实现是基于cookie的
- 第一次访问 会创建session对象 将其id与值通过 set-cookie 响应头传递给客户端浏览器,客户端浏览器会在本地缓存将id值保存
- 第二次访问 会在请求头中将id值 通过cookie 传递给服务器 第二次创建就可以根据id值找到第一次创建的session对象
-
细节:
1.客户端关闭,服务器不关闭 获取到的session是否为同一个?
-
默认情况 不是
-
如果需要相同, 创建一个cookie 键为JSESSIONID 设置最大存活时间 让cookie持久化存储.
Cookie cookie = new Cookie("JSESSIONID", session.getId()); cookie.setMaxAge(60*60); response.addCookie(cookie);
- 客户端不关闭,服务器关闭 获取到的session是否为同一个?
-
不是同一个, 要确保数据不丢失, tomcat自动帮你完成以下操作:
-
session的钝化:
在服务器正常关闭之前,将session对象序列化到硬盘上
-
session的活化:
在服务器启动后,将session文件转化为内存中的session对象
-
-
-
session什么时候会被销毁?
-
服务器关闭时被销毁
-
session.invalidate():自动销毁
-
session默认关闭时间为30min
-
C:\Users\MrDong\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Tomcat_8_5_31_java_123_9\conf
//可以手动修改web.xml中配置(项目中的该配置)
<session-config>
<session-timeout>30</session-timeout>
</session-config>
-
session的特点
-
session用于存储一次会话的多次请求的数据 存储在服务器端
-
session可以存储任意类型 任意大小的数据
-
-
session域cookie的区别 面试考点
- session 在服务器端,cookie 在客户端(浏览器)
- session存储没有数据大小限制 cookie 有
- session存储的数据比较安全 cookie相对不安全