一、会话管理
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 {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//创建cookieCookie 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 {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取请求中携带的cookieCookie[] cookies = req.getCookies();//请求中的多个cookie会进入该数组 请求中如果没有cookie cookies数组是nullif(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 {@Overrideprotected 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的idSystem.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 {@Overrideprotected 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 {@Overrideprotected 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 {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取请求域中的数据String request = (String)req.getAttribute("request");System.out.println("请求域:"+request);//获取会话域中的数据//获得sessionHttpSession 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);}}
这些是我听尚硅谷课程记下的笔记。