会话 一次交互(一次请求+一次响应) 一次会话(n次交互) 主要功能:在会话过程中起到共享数据的作用
一.为什么需要会话控制
保持用户登录状态,就是当用户在登录之后,会在服务器中保存该用户的登录状态,当该用户后续访问该项目中的其它动态资源(Servlet或者Thymeleaf)的时候,能够判断当前是否是已经登录过的。而从用户登录到用户退出登录这个过程中所发生的所有请求,其实都是在一次会话范围之内
二. 域对象的范围
应用域的范围
整个项目部署之后,只会有一个应用域对象,所有客户端都是共同访问同一个应用域对象,在该项目的所有动态资源中也是共用一个应用域对象
请求域的范围
每一次请求都有一个请求域对象,当请求结束的时候对应的请求域对象也就销毁了
会话域的范围
会话域是从客户端连接上服务器开始,一直到客户端关闭,这一整个过程中发生的所有请求都在同一个会话域中;而不同的客户端是不能共用会话域的
三 .Cookie技术(客户端的会话技术)
1 .Cookie的概念
Cookie是一种客户端的会话技术,它是服务器存放在浏览器的一小份数据,浏览器以后每次访问该服务器的时候都会将这小份数据携带到服务器去。
2. Cookie的应用场景
2.1记住用户名 当我们在用户名的输入框中输入完用户名后,浏览器记录用户名,下一次再访问登录页面时,用户名自动填充到用户名的输入框.
2.2保存电影的播放进度
在网页上播放电影的时候,如果中途退出浏览器了,下载再打开浏览器播放同一部电影的时候,会自动跳转到上次退出时候的进度,因为在播放的时候会将播放进度保存到cookie中
3 .Cookie的入门案例(在这里面我们看到案例是视频案例 笔记案例请回看笔记)
数据存储在客户端
① 如何将数据保存到cookie内
//创建Cookie对象并设置数据
Cookie cookie01=new Cookie("adminKey","adminValue");
//将cookie添加到响应报文内
response.addCookie(cookie01);
课堂代码: 课堂代码有个问题就是BaseServlet是啥 为啥不真的继承HttpServlet(不过最后都得继承HttpServlet )如下所示:public class ServletDemo01 extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1. 创建一个cookie对象,用于存放键值对 Cookie cookie = new Cookie("cookie-message","hello-cookie"); //2. 将cookie添加到response中 //底层是通过一个名为"Set-Cookie"的响应头携带到浏览器的 response.addCookie(cookie); } }
public class CookieServlet extends BaseServlet { protected void addCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1. 创建Cookie对象并设置数据 Cookie cookie01=new Cookie("adminKey","adminValue"); Cookie cookie02=new Cookie("rootKey","rootValue"); //2. 将cookie添加到响应报文内 response.addCookie(cookie01); response.addCookie(cookie02); //3. 给响应 }
测试: cookie数据的特点: a. 一旦cookie被保存到客户端,在以后的每次请求中都会带着所有的cookie 测试: 回退后 在重新发请求 变成自己设置的Cookie 谷歌打开的 火狐打开的 在同一个浏览器新开一个窗口,输入上一步操作的网址后 发现是cookie是带着,当我们用其他浏览器打开同一个网址时 发现coookie并没有带着 这是因为不同的浏览器是相当于不同的客户端 如谷歌和火狐二个浏览器是不同的二个客户端 b. 此时添加cookie被称为瞬时cookie,浏览器关闭cookie就消失(浏览器关闭会话就会结束)
② 如何将数据从cookie中取出来
Cookie[] cookies = request.getCookies();
protected void getCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for (Cookie cookie : cookies) {
System.out.println(cookie.getName());
System.out.println(cookie.getValue());
}
}
测试
③ cookie中的数据的有效时间
如果我们不设置Cookie的时效性,默认情况下Cookie的有效期是一次会话范围内,我们可以通过cookie的setMaxAge()方法让Cookie持久化保存到浏览器上
-
会话级Cookie
-
服务器端并没有明确指定Cookie的存在时间
-
在浏览器端,Cookie数据存在于内存中
-
只要浏览器还开着,Cookie数据就一直都在
-
浏览器关闭,内存中的Cookie数据就会被释放
-
-
持久化Cookie
-
服务器端明确设置了Cookie的存在时间
-
在浏览器端,Cookie数据会被保存到硬盘上
-
Cookie在硬盘上存在的时间根据服务器端限定的时间来管控,不受浏览器关闭的影响
-
持久化Cookie到达了预设的时间会被释放
-
cookie.setMaxAge(int expiry)
参数单位是秒,表示cookie的持久化时间,如果设置参数为0,表示将浏览器中保存的该cookie删除
在添加到响应之前之前,需要设置一个时间 cookie01.setMaxAge(60);//单位是秒
protected void addCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 创建Cookie对象并设置数据
Cookie cookie01=new Cookie("adminKey","adminValue");
Cookie cookie02=new Cookie("rootKey","rootValue");
//设置有效时间
cookie01.setMaxAge(600);//单位是秒
cookie01.setPath(request.getContextPath()+"/user");//设置一个uri
//2. 将cookie添加到响应报文内
response.addCookie(cookie01);
response.addCookie(cookie02);
//3. 给响应
}
测试:
回退 获取
接下去关闭浏览器 然后打开浏览器重新获取会消失一个cookei
也就是说cookie01可以存在60秒 浏览器关闭后在重新打开还是在的(60秒内),等过了60秒后
如果关闭浏览器cookie01就会消失
④ 设置cookie的携带条件
上网时间长了,本地会保存很多Cookie。对浏览器来说,访问互联网资源时不能每次都把所有Cookie带上。浏览器会使用Cookie的path属性值来和当前访问的地址进行比较,从而决定是否携带这个Cookie。
设置什么请求路径下携带该cookie 在添加之前设置一个请求路径
cookie01.setPath(request.getContextPath()+"/user");//设置一个uri
设置cookie01只有在访问当前项目下的user下的请求时才会携带
我们可以通过调用cookie的setPath()方法来设置cookie的path
主要在/user下面的请求都可以获取得到
cookei的练习
登录页面:记住用户和密码
① 搭建thymeleaf的环境 jar包 粘贴ViewBaseServlet 配置前缀和后置 ② 准备登录页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<base th:href="@{/}">
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<form action="user?flag=login" method="post">
username:<input type="text" name="username" th:value="${username}"/><br>
password:<input type="password" name="password" th:value="${password}"/><br>
<input type="checkbox" name="confirm"/>记住用户名和密码<br>
<input type="submit" value="登录"/>
</form>
</body>
</html>
③ UserServlet
测试:
关闭浏览器 在重新打开
回退 刷新
因为目前还没有设置时间,所以在不关闭浏览器的情况下 ,新型窗口 重新输入网址 登录 还是一样存在,但是如果一旦关闭浏览器就没有了
设置持久化
这时如果关闭浏览器后 在重新登录的情况下 密码没有了 但是用户名还在
如果用户自行把cookei给清理了 那么要重新登录时就不会记住了
合起来代码:
public class UserServlet extends BaseServlet {
protected void toLoginPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username="";
String password="";
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for (Cookie cookie : cookies) {
if(cookie.getName().equals("username")){
username=cookie.getValue();
}
if(cookie.getName().equals("password")){
password=cookie.getValue();
}
}
}
request.setAttribute("username",username);
request.setAttribute("password",password);
this.processTemplate("login",request,response);
}
protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
PrintWriter writer = response.getWriter();
if(username.equals("admin")&&password.equals("root")){
//登录成功
String confirm = request.getParameter("confirm");
System.out.println("confirm = " + confirm);
if(confirm!=null){
//将用户名和密码保存到cookie内
Cookie usernameCookie=new Cookie("username",username);
Cookie passwordCookie=new Cookie("password",password);
usernameCookie.setMaxAge(60*60);
response.addCookie(usernameCookie);
response.addCookie(passwordCookie);
}
writer.write("success");
}else{
//登录失败
writer.write("error");
}
}
}