一、会话管理
1、什么是会话?
会话是客户端和服务端之间进行多次的请求和响应。
相当于两个人聊天,进行了多次的问答。
对多次问答的管理叫做会话管理,管理的东西是通信状态。
2、什么是状态?
举例: 小明去校园食堂买粥,觉得牛奶燕麦粥不错,之后又去买粥了,对食堂阿姨说,还是上次的那种粥。
无状态: 阿姨没有记录小明是否来过,更没有记录小明上次点的是那种粥,只能小明重新说一遍粥的名字。
有状态: 小明来喝粥的时候,阿姨把小明喝的是那种粥记录在小本本上,下次小明再来的时候,阿姨直接查询 小本本,给小明要喝的粥(避免小明早八迟到 )。
3、经典场景
用户在客户端上,进行了登录,之后可能去做一系列的操作,会向服务端发送一系列请求,服务端会判断(判断的是客户端的状态)客户端有没有进行登录?如果是登录的状态有些操作可以做,如果是未登录的状态有些操作是不能做的。
HTTP是无状态的协议,不能记录客户端的状态,这就需要使用Cookie、Session来记录客户端的状态。
4、记录客户端状态图示
Cookie和Session记录客户端状态图示
二、Cookie
1、概述
Cookie是一种客户端会话技术,Cookie是由服务端产生的,是存放在浏览器上的一小份数据,浏览器每次请求服务器的时,都会携带浏览器中的Cookie。
Cookie的时效性分为:会话级Cookie 和 持久化Cookie。
默认情况下Cookie是会话级别的Cookie,只要浏览器不关闭,Cookie就一直存在。
持久化Cookie,可以设置Cookie的存活时间,就算浏览器关闭,Cookie也不会消失,只有到达存活时间之后Cookie才会消失,可以使用cookie.setMaxAge(int expiry),设置存活时间,参数的单位是“秒”。
设置Cookie的提交路径,只有在请求自己设置的提交路径时,才会携带Cookie值,设置方法cookie.setPath(String path)。
2、原理图
3、代码测试
ServletA:创建cookie
package com.lyh.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/servletA")
public class ServletA extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建cookie
Cookie cookie1 = new Cookie("keya","valuea");
//设置cookie的有效时间
//cookie1.setMaxAge(60*5);
//设置cookie的提交路经
cookie1.setPath("/java_web/servletB");
Cookie cookie2 = new Cookie("keyb","valueb");
//将cookie 放入response对象
resp.addCookie(cookie1);
resp.addCookie(cookie2);
}
}
ServletB:获取cookie
package com.lyh.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/servletB")
public class ServletB extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求中携带的cookie
Cookie[] cookies = req.getCookies();
//请求中的多个cookie会进入该数组 请求中如果没有cookie cookies数组是null
if(cookies != null){
for (Cookie cookie : cookies) {
System.out.println(cookie.getName()+"="+cookie.getValue());
}
}
}
}
三、Session
1、概述
Session全称叫HttpSession,是保留更多信息在服务端的一种技术,服务端为每一个客户端开辟一块内存空间,就是Session对象,客户端在发送请求的时,都可以使用自己的Session,服务端通过Session来记录每个客户端的状态信息。
Session的时效性默认是30分钟
Session的使用要配合Cookie。
在web.xml中设置Session的失效时间,单位是“分钟”。
<session-config>
<session-timeout>30</session-timeout>
</session-config>
设置个别session的最大失效时间: session.setMaxInactiveInterval(int var1); 单位是“秒”
直接让session失效: session.invalidate();
应用场景:
- 记录用户的登录状态。
- 记录用户的操作历史(购物车)。
2、原理图
3、 代码测试
Servlet1:获取session 并向session中存储数据。
package com.lyh.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* 获取session 并向session中存数据
*/
@WebServlet("/servlet1")
public class Servlet1 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//接收请求中的username参数
String username = req.getParameter("username");
//获得session对象
HttpSession session = req.getSession();
//设置这个session的失效时间
session.setMaxInactiveInterval(120);
//判断请求中有没有一个特殊的cookie JSESSIONID 值**** ****
//1 有
// 根据JESSIONID找对应session对象
// 1 找到了
// 返回之前的session
// 2 没找到
// 创建一个新的session返回,并且向response对象中存放一个JESSIONID 的cookie
//2 没有
// 创建一个新的session返回,并且向response对象中存放一个JESSIONID 的cookie
//打印一下session的id
System.out.println(session.getId());
System.out.println(session.isNew());
//将username存入session
//值是 Object类型的,session中 可以存储任何类型的数据
session.setAttribute("username",username);
//向客户端响应信息
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("成功");
}
}
Servlet2:获取session,读取session中存储的数据。
package com.lyh.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/servlet2")
public class Servlet2 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获得session对象
HttpSession session = req.getSession();
System.out.println(session.getId());
System.out.println(session.isNew());
//读取session中存储的用户名
String username = (String) session.getAttribute("username");
System.out.println("servlet2 得到了 username:" + username);
}
}
四、三大域对象
域对象: 一些用于存储和传递数据的对象称之为域对象。“域”表示的是不同的范围和区域。每一个范围和区域都可以用不同的对象来代表,这就是域对象。
请求域: HttpServletRequest,传递的数据范围是一次请求之内以及请求转发。
会话域: HttpSession,传递的范围是一次会话之内,可以跨多个请求。
应用域: ServletContext,传递的范围是本应用之内,可以跨多个会话。
生活举例:
1、暖壶摆放在张三的工位上,只有张三一个人可以用——请求域
2、暖壶摆放在办公室的公共区域,这个办公室内的所有人都可以用——会话域
3、暖壶摆放在整个楼层的走廊上,整个楼层的人都可以使用——应用域
域的API:
所有域图示:
代码测试实现:
ServletA:向不同域中存放数据
package com.lyh.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/servletA")
public class ServletA extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//向请求域中存放数据
req.setAttribute("request","requestMessage");
//向会话域中存放数据
HttpSession session = req.getSession();
session.setAttribute("session","sessionMessage");
//向应用域存放数据
ServletContext application = getServletContext();
application.setAttribute("application","applicationMessage");
//获得请求域中的数据
String request = (String) req.getAttribute("request");
System.out.println("请求域(ServletA):"+request);
//请求转发到 ServletB 中
req.getRequestDispatcher("servletB").forward(req,resp);
}
}
ServletB:获取各种不同域中的数据
package com.lyh.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.io.IOException;
@WebServlet("/servletB")
public class ServletB extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求域中的数据
String request = (String)req.getAttribute("request");
System.out.println("请求域:"+request);
//获取会话域中的数据
//获得session
HttpSession session = req.getSession();
String sessionV = (String)session.getAttribute("session");
System.out.println("会话域:"+sessionV);
//获取应用域中的数据
//获取 application域 对象
ServletContext application = getServletContext();
String applicationV = (String) application.getAttribute("application");
System.out.println("应用域:"+applicationV);
}
}
这些是我听尚硅谷课程记下的笔记。