一、会话技术
问题引入:在一个商城系统中,要想实现用户未登录状态下,将商品保存到购物车中,因为用户没有登录,于是不能讲购物车数据保存到数据库中,因此就可以使用会话技术将数据保存下来。会话技术分为两种:存储在服务器上的技术——session技术和存储在客户端的技术——cookie技术。这两种技术都称为会话技术。
1.会话的概念
所谓的会话,指的客户端与一个web应用进行交互的过程,
会话的开始是当客户端打开浏览器与该web应用进行交互,即表示会话开始,
会话的结束时当客户端关闭浏览器即表示会话的结束。
2.相应的技术点
一个会话过程中需要存储数据,那么数据要么存在客户端,要么存在服务器,因此与客户端相应的技术就是Cookie,与服务端相应的技术就是Session
二、会话技术之Cookie技术
1.主要解决两个问题:
解决第一个问题:如何把数据存储到Cookie中并发送给客户端
//1.创建Cookie对象,向Cookie对象中存入数据
Cookie cookie = new Cookie("name","dongdong");
//2.把Cookie发送给客户端
response.addCookie(cookie);
解决第二个问题:如何获得客户端携带的Cookie并获得Cookie中的数据。
//1.通过request对象获得客户端携带过来的所有的Cookie,注意,客户端会自动携带Cookie过来(视情况而定)
Cookie[] cookies = request.getCookies();
//2.如果客户端有Cookie则遍历所有的Cookie
if(cookies!=null){
for (Cookie cookie : cookies) {
//3.寻找键是name的Cookie
if("name".equals(cookie.getName())){
//4.获得该Cookie的值
String value = cookie.getValue();
System.out.println(value);
}
}
}
2.Cookie相关的API
1)长期保存Cookie——设置Cookie的存活时间
Cookie默认情况下是存储在浏览器的缓存中,随着会话的结束,Cookie被销毁。那么如果想长期保存Cookie,就可以通过设置Cookie的存活时间。——setMaxAge(秒值)
当长期保存Cookie后,Cookie就不再是保存在浏览器的缓存中,而是保存在客户端的本地磁盘中。比如浏览器用于存储Cookie等临时文件的文件夹内。
2)客户端在访问怎样的资源时会携带Cookie——设置Cookie的路径
· 默认情况下客户端在访问当前web应用时都会携带由当前web应用产生的Cookie到服务器。
· 当客户端设置了Cookie的路径,那么在客户端在访问该路径下的任何资源,都能携带Cookie过去。
cookie.setPath("/")=====http://localhost:8080服务器下的任何资源都会携带该Cookie
cookie.setPath("/day11")=====day11这个web应用下的任何资源都会携带Cookie,这是Cookie的默认路径
cookie.setPath("/day11/login")=====day11这个web应用下的login下的任何资源都会携带Cookie
3)如何删除Cookie: setMaxAge(0) 立即删除,不会再让Cookie存在在浏览器缓存中。
· 删除不长期保存的Cookie
//覆盖Cookie的键值对(要保证被覆盖的Cookie的路径相同),让其成为空
Cookie cookie = new Cookie("name","");
//彻底删除Cookie
cookie.setMaxAge(0);
· 删除长期保存的Cookie
注意:相同键的Cookie只能是唯一的,后面的Cookie会覆盖前面相同键的Cookie,前提是这两个的路径相同。
//创建一个与要删除的Cookie相同键的Cookie用于覆盖,如果要删除的Cookie设了路径,那么这个Cookie也要设成相同路径。
Cookie cookie = new Cookie("name","");
//设置该Cookie的存活时间是0,也就意味着删除
cookie.setMaxAge(0);
response.addCookie(cookie);
Cookie存储在客户端中,相同路径下的Cookie键是唯一的。因此要删除Cookie,通过再创建一个Cookie,对这个Cookie设置存活时间为0,然后覆盖掉原Cookie,并且保证这两Cookie的路径相同,因为路径相同才能覆盖。
3.案例之记录用户上次的登录时间
//解决response的中文乱码问题
response.setContentType("text/html;charset=utf-8");
//1.创建Cookie,往Cookie里面塞入当前时间的键值对
//yyyy-MM-dd
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = sdf.format(new Date());
Cookie cookie = new Cookie("LastAccessTime", time);
//2.向客户端发送该Cookie
response.addCookie(cookie);
//========================
//3.获得客户端携带的所有的Cookie
Cookie[] cookies = request.getCookies();
//如果Cookie不为空
if(cookies!=null){
//遍历Cookies数组
for (Cookie cookie2 : cookies) {
//找到键是LastAccessTime的Cookie对象
if("LastAccessTime".equals(cookie2.getName())){
//获得该Cookie的值
String value = cookie2.getValue();
//非第一次登录:
response.getWriter().write("您上次登录的时间是:"+value);
}else{
//如果没有LastAccessTime这个Cookie,是第一次登录,没有Cookie
response.getWriter().write("您是第一次登录!");
}
}
}else{
//如果没有Cookie,是第一次登录,没有Cookie
response.getWriter().write("您是第一次登录!");
}
三、会话技术之Session技术
1.Session技术的分析
1.服务器创建好Session空间后会把Session空间的编号封装到Cookie中并发送给客户端,该Cookie的键:JSESSIONID
2.当客户端再次与web应用会话时,就会带着该Cookie过来,如果需要使用session空间,就会从Cookie中找到JSESSIONID,根据JSESSIONID找到相应的Session空间。
详见图解
2.Session技术的实现
需要通过session解决两个问题:
· 如何获得session域对象(如何获得服务器为客户端开辟的空间)
· 如何向session域对象存取值:
1)和获得Session域对象
HttpSession session = request.getSession();
(1)如果服务器没有为该客户端开辟过空间(服务器怎么判断有没有为该对象创建过空间?),那么就为该客户端新开辟一个空间。此时session指向该空间。
怎么判断的?根据客户端有没有JSESSIONID的Cookie。如果没有根据JSESSIONID的值找到对应的空间或者没有JSESSIONID,那么就新开辟一个空间。
(2)如果服务器已经为该客户端开辟过空间(怎么判断的?),那么就将已经存在的空间给session对象的引用。
怎么判断的? 通过客户端携带的Cookie的JSESSIONID的值来寻找服务器上的Session空间。
2)向session域对象存取值
//往session中存值
session.setAttribute("name", "dongdong");
//从session中取值
String name = (String) session.getAttribute("name");
//从session中移除值
session.removeAttribute("name");
3.Session的生命周期
· 创建:第一次执行request.getSession()时创建
· 销毁:
1)在web.xml配置了session的timeout,那么时间一到,session就被销毁,注意从何时开始计时?从与该web应用没有任何会话(操作)时开始计时。
2)通过session的invalidate()方法来手动销毁session空间
3)服务器非正常关闭时,比如断电。那么这个Session就来不及备份(钝化),那么该session就销毁了。
4.Session的作用范围
Session的默认作用范围是在一次会话中,因为Cookie默认情况下是存活在一次会话中。第二次会话时Cookie已被销毁。那么如果在第二次会话时也想访问到之前的Session,让之前的Cookie长期保存。
5.多次会话中访问同一Session
因为会话结束,服务器上的Session可以长期保存(默认是30分钟,也可以设置成更长的时间)
//获得session空间
HttpSession session = request.getSession();
//存入键值对
session.setAttribute("name", "dongdong");
//得到该Session空间的编号
String id = session.getId();
System.out.println(id);
//人工创建一个Cookie,该Cookie中保存Session空间的编号
Cookie cookie = new Cookie("JSESSIONID",id);
//让Cookie长期存活,这样在多次会话中就能通过该Cookie找到之前的那个session空间。
cookie.setMaxAge(60*60*24*7);
//把Cookie发送给客户端
response.addCookie(cookie);
6.删除多次会话中能够访问到的Session空间
要么删除长期保存的Cookie,让第二次会话不会携带Cookie过去,
要么删除服务器上的Session,让第二次会话携带的Cookie找不到相应的Session
要么两者都删除
//删除session
HttpSession session = request.getSession();
session.invalidate();
//获得客户端携带的所有Cookie
Cookie[] cookies = request.getCookies();
if(cookies!=null){
//遍历Cookie
for (Cookie cookie : cookies) {
//找到键是JSESSIONID的Cookie
if("JSESSIONID".equals(cookie.getName())){
//将这个Cookie删除
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
}