一、会话技术
1.什么是会话
- 会话:就是为了实现某一个功能,客户端和服务器之间可能会产生多次的请求和响应,从客户端访问服务器开始,到最后访问服务器结束,这期间产生的多次请求和响应加在一起就称为客户端和服务器之间的一次会话
- HTTP1.0协议规定一次请求一次响应后断开连接每一次请求都是一个崭新的请求.但是一次会话往往需要跨越多个请求,如何保存在每次请求中产生的临时数据,是必须要解决的一个问题.解决方案有2种:
- 第一种是将临时数据保存在客户端浏览器上,用户每次访问时,将会话的临时数据在请求中带给服务器(Cookie)
- 另一种方案是将会话数据保存在服务器上,给每个用户一个身份标识,根据用户的身份标识,找到保存在服务器上的数据(Session)
二、Cookie
1.什么是Cookie
HTTP Cookie(也叫 Web Cookie或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地客户端的一小块数据
,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能。
- Cookie 主要用于以下三个方面:
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
2.应用场景
- 自动登陆,保存账号密码
- 浏览记录
- 购物车
3.为什么要有这个Cookie
http的请求是无状态
。 客户端与服务器在通讯的时候,是无状态的,其实就是客户端在第二次来访的时候,服务器根本就不知道这个客户端以前有没有来访问过。 为了更好的用户体验,更好的交互 [自动登录],其实从公司层面讲,就是为了更好的收集用户习惯[大数据]
4.Cookie的使用
- 添加给Cookie客户端
- 1.在响应的时候,添加cookie
// 创建Cookie
Cookie cookie = new Cookie("aa", "bb");
//向响应中添加一个Cookie, 可以在一次响应中添加多个Cookie
response.addCookie(cookie);
- 2.客户端收到的信息里面,响应头中多了一个字段 Set-Cookie
//获取客户端带过来的cookie
Cookie[] cookies = request.getCookies();
if(cookies != null){
for (Cookie c : cookies) {
String cookieName = c.getName();
String cookieValue = c.getValue();
System.out.println(cookieName + " = "+ cookieValue);
}
}
5.Cookie的常用API方法
//关闭浏览器后,cookie就没有了 ---> 针对没有设置cookie的有效期。
// expiry: 有效 以秒计算。
//正值:表示 在这个数字过后,cookie将会失效。
//负值:关闭浏览器,那么cookie就失效默认,值是 -1
cookie.setMaxAge(60 * 60 * 24 * 7);
//赋值新的值
cookie.setValue(newValue);
//用于指定只有请求了指定的域名,才会带上该cookie
cookie.setDomain(".baidu.com");
//只有访问该域名下的cookieDemo的这个路径地址才会带cookie
cookie.setPath("/CookieDemo");
6.判断账号是否正确
- 如果正确,则获取cookie。 但是得到的cookie是一个数组, 我们要从数组里面找到我们想要的对象。
- 如果找到的对象为空,表明是第一次登录。那么要添加cookie
- 如果找到的对象不为空, 表明不是第一次登录。
if("admin".equals(userName) && "123".equals(password)){
//获取cookie last-name --- >
Cookie [] cookies = request.getCookies();
//从数组里面找出我们想要的cookie
Cookie cookie = CookieUtil.findCookie(cookies, "last");
//是第一次登录,没有cookie
if(cookie == null){
Cookie c = new Cookie("last", System.currentTimeMillis()+"");
c.setMaxAge(60*60); //一个小时
response.addCookie(c);
response.getWriter().write("欢迎您, "+userName);
}else{
//1. 去以前的cookie第二次登录,有cookie
long lastVisitTime = Long.parseLong(cookie.getValue());
//2. 输出到界面,
response.getWriter().write("欢迎您, "+userName +",上次来访时间是:"+new Date(lastVisitTime));
//3. 重置登录的时间
cookie.setValue(System.currentTimeMillis()+"");
response.addCookie(cookie);
}
}else{
response.getWriter().write("登陆失败 ");
}
7.清除浏览记录
- 其实就是清除Cookie, 删除cookie是没有什么delete方法的。只有设置maxAge 为0 。
Cookie cookie = new Cookie("history","");
cookie.setMaxAge(0); //设置立即删除
cookie.setPath("/CookieDemo02");
response.addCookie(cookie);
8.Cookie的总结
- 1.服务器给客户端发送过来的一小份数据,并且存放在客户端上。
- 2.获取cookie, 添加cookie
request.getCookie();
response.addCookie();
- 3.Cookie分类
- 会话Cookie
默认情况下,关闭了浏览器,那么cookie就会消失。 - 持久Cookie
在一定时间内,都有效,并且会保存在客户端上。
- 会话Cookie
cookie.setMaxAge(0); //设置立即删除
cookie.setMaxAge(100); //100 秒
- 4.Cookie的安全问题。
由于Cookie会保存在客户端上,所以有安全隐患问题。 还有一个问题, Cookie的大小与个数有限制。 为了解决这个问题 —> Session .
三、Session讲解
- Session 代表着服务器和客户端一次会话的过程。
- Session 对象存储特定用户会话所需的属性及配置信息。
- 这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当客户端关闭会话,或者 Session 超时失效时会话结束。
- Session是基于Cookie的一种会话机制,Session是数据存放在服务端。
2.Session常用的API
HttpSession session = request.getSession();//获取session,没有则创建
session.getId();//获取sessionId
session.getAttribute("key");//获取存储的某个值
session.setAttribute("key","value");//存储数据,value是object类型
session.getCreationTime();//获取session创建的时间
session.removeAttribute("key");//移除某个数据
session.invalidate();//重置session,使session失效
session.setMaxInactiveInterval(1*60*60);//设置会话的超时时间(单位:秒),默认30分钟
session.getLastAccessedTime();//最后一次修改session的时间
3.Session的生命周期
- 创建
在Servlet里面第一次调用
request.getSession()
方法时创建Session
- 销毁
- 1.意外死亡
当服务器非正常关闭时,随着应用的销毁,session销毁。
当服务器正常关闭,则未超时的session将会以文件的形式保存在tomcat服务器的work目录下,这个过程叫session的钝化
,当服务器再次启动时,钝化的session还可以恢复过来,这个过程叫做session的活化
。
- 2.session的会话时间过期,默认有效期:30分钟
- 3.自杀:当调用
session.invalidate()
方法时session立即销毁。
注意
- session 是存放在服务器的内存中的一份数据。 当然可以持久化.
- Redis . 即使关了浏览器,session也不会销毁。
4.案例
response.setContentType("text/html;charset=utf-8");
//1. 获取要添加到购物车的商品id
int id = Integer.parseInt(request.getParameter("id"));
String [] names = {"Iphone7","小米6","三星Note8","魅族7" , "华为9"};
//取到id对应的商品名称
String name = names[id];
//2. 获取购物车存放东西的session Map<String , Integer> iphoen7 3
//把一个map对象存放到session里面去,并且保证只存一次。
Map<String,Integer>map=(Map<String,Integer>)request.getSession().getAttribute("cart");
//session里面没有存放过任何东西。
if(map == null){
map = new LinkedHashMap<String , Integer>();
request.getSession().setAttribute("cart", map);
}
//3. 判断购物车里面有没有该商品
if(map.containsKey(name)){
//在原来的值基础上 + 1
map.put(name, map.get(name) + 1 );
}else{
//没有购买过该商品,当前数量为1 。
map.put(name, 1);
}
//4. 输出界面。(跳转)
response.getWriter().write("<a href='product_list.jsp'><h3>继续购物</h3></a><br>");
response.getWriter().write("<a href='cart.jsp'><h3>去购物车结算</h3></a>");
- 移除Session中的元素
//强制干掉会话,里面存放的任何数据就都没有了。
session.invalidate();
//从session中移除某一个数据
session.removeAttribute("cart");
常见面试题
1.请求转发和重定向
- 重定向
之前的写法
response.setStatus(302);
response.setHeader("Location", "login_success.html");
//重定向写法: 重新定位方向 参数即跳转的位置
response.sendRedirect("login_success.html");
1. 地址上显示的是最后的那个资源的路径地址
2. 请求次数最少有两次,服务器在第一次请求后,会返回302,以及一个地址, 浏览器在根据这个地址,执行第二次访问。
3. 可以跳转到任意路径。 不是自己的工程也可以跳。
4. 效率稍微低一点, 执行两次请求。
5. 后续的请求,没法使用上一次的request存储的数据,或者没法使用上一次的request对象,因为这是两次不同的请求。
- 请求转发
//请求转发的写法: 参数即跳转的位置
request.getRequestDispatcher("login_success.html").forward(request, response);
1. 地址上显示的是请求servlet的地址。 返回200 ok
2. 请求次数只有一次, 因为是服务器内部帮客户端执行了后续的工作。
3. 只能跳转自己项目的资源路径 。
4. 效率上稍微高一点,因为只执行一次请求。
5. 可以使用上一次的request对象。
2.Cookie和Session的区别
- (1) Cookie是将会话中产生的数据保存在客户端, 是客户端的技术
- (2) Cookie保存的信息的时间比较长, 但是安全性不高. 可能随着用户的操作, Cookie会被清空, 所以Cookie存储数据的稳定性比较差.因此Cookie适合存放要保存时间较长, 但安全性要求不高的信息
- (3) Session是将会话中产生的数据保存在服务器端, 是服务器端的技术
- (4) Session通常保存信息的时间比较有限,但安全性比较高,因为是保存在服务器端, 不会随着用户的操作而导致Session意外丢失,因此session适合存放安全性要求比 较高, 但是不需要长时间保存的数据.