目录
状态:协议记住用户及其请求的能力
HTTP协议是无法记住用户和其请求的,表现为客户端第二次请求时不知道客户端的身份信息

客户A第一次请求登录,登录成功了;第二次请求加货物到购物车,因为HTTP协议是无状态的,不可以记录用户信息和追踪请求,导致服务器不知道当前请求的用户是谁,也就不知道加到谁的购物车里,无法做出响应
但是,按照设想,客户端是可以实现多次加货物到购物车的,并且服务器追踪所有请求,记录购物车的商品并计算总价;为了实现这一点,就需要追踪所有请求并和用户相关联
会话跟踪技术就成了对HTTP无状态协议的一种扩展
Cookie和Session就是保持状态的记录,session底层依赖于cookie
cookie类似于你去坐火车,买票的时候有一个票据,记录了你的位置信息,比如(8号车厢20座位),根据这个位置你就可以知道自己的座位在哪,这个票据就是cookie
Cookie是服务器响应给客户端,并且存储在客户端的一份小数据。下次客户端访问服务器时,会自动带上这个Cookie。服务器通过Cookie就可以区分客户端

对cookie的管理需要使用javax.servlet.http.Cookie类
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- //1、创建cookie实例
- //键值对的形式,name是键值对的key,”张三“是value
- Cookie cookie = new Cookie("name", "张三");
- //key固定了 value可以修改
-
- //2、获取cookie名称
- System.out.println(cookie.getName());
- //3、获取cookie的值
- System.out.println(cookie.getValue());
- //4、给cookie设置新的值
- cookie.setValue("李四");
- //5、设置cookie的所在的域名
- cookie.setDomain("127.0.0.1");
- //6、返回cookie的域名
- System.out.println(cookie.getDomain());
- }
- }

Cookie的管理,应该包括两个方面,服务器给客户端发送cookie,从客户端读取cookie
- @WebServlet("/sendcookie")
- public class SendCookie extends HttpServlet {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- //1、创建cookie对象
- Cookie cookie = new Cookie("username", "张三");
- //2、设置cookie的最大存活时间 这个cookie是存储在浏览器的内存中的,随着浏览器关闭,cookie就会消失
- //如果想让cookie存储在磁盘上,就可以设置cookie的最大存活时间
- //单位是s,如果参数为负数,表示不在硬盘存储,=0,表示删除这个cookie
- cookie.setMaxAge(60*60);
- //3、给客户端发送cookie对象
- resp.addCookie(cookie);
-
- resp.setContentType("text/html;charset=utf8");
- PrintWriter out=resp.getWriter();
- out.println("" +
- ""
- +"
"
+"已经发送了cookie" - +""
- );
- }
- }
执行之后,服务器将会在浏览器上写一个cookie文件
查看浏览器cookie



如果不设置持久化存储,cookie是保留在浏览器的内存的,随着浏览器的关闭,cookie就消失了,下一次用户就要重新登录
- @WebServlet("/readcookie")
- public class ReadCookie extends HttpServlet {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- String name = "username";
- String value = null;
- Cookie[] cookies = req.getCookies();//得到请求的所有cookie对象
- if (cookies != null) {
- for (int i = 0; i < cookies.length; i++) {
- if (cookies[i].getName().equals(name)) {
- value = cookies[i].getValue();
- break;
- }
- }
- }
- resp.setContentType("text/html;charset=utf8");
- resp.getWriter().write("" + "
"
+ name + value + "" + ""); - }
- }

cookie是保留在客户端的,可以被人为删除,而且只要你的电脑被黑,数据就可能丢失
并且,cookie是有大小限制的。通常,一个浏览器只允许最多存放300个Cookie,每一个站点的Cookie最多20个,每一个Cookie的大小限制为4kb
可能是出于cookie的安全性和cookie的大小限制,cookie每一次都要在请求中传输导致的速率等问题,提出了Session
Session,会话,是一个客户与服务器之间的不间断的请求响应序列。
session是存在于服务器的

如果使用cookie,那么可能账户,密码等信息直接保存在客户端,并且每次都要传输到客户端

使用Session,那么Cookie内不将会保存密码等重要信息,数据更加安全,而且Cookie内的数据也会减少,可以提高传输效率
sessionid通常是一个32位的16进制数字
通过javax.servlet.http.HttpSession来管理会话
- @WebServlet("/new")
- public class SessionAPI extends HttpServlet {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- //1、创建会话
- // 使用HttpServletRequest的getSession()方法 创建和请求关联的会话,如果会话存在,直接返回会话,如果不存在,创建新的会话
- HttpSession session = req.getSession();
- System.out.println("SessionId" + session.getId());//返回SessionId
- System.out.println("会话创建的时间" + session.getCreationTime());//会话创建的时间 时间从1970.1.1午夜到现在的毫秒数
- System.out.println("新会话" + session.isNew());//如果这个会话没有和任何对象关联 返回true
- session.setAttribute("name", "张三");//将一个键值对属性 写入session
- // session.invalidate();//删除session
- System.out.println(session.getAttribute("name"));//得到key对应的value值
- session.setMaxInactiveInterval(10);//设置在会话失效之前,两个请求之间的最大间隔时间 单位s
-
- Enumeration<String > names= session.getAttributeNames();//得到所有属性的name
- while(names.hasMoreElements()) {
- String name = names.nextElement();
- System.out.println(name + session.getAttribute("name"));
- }
- session.removeAttribute("name");//删除某一属性
- }
- }



我们并没有说把这个SessionId打包到了Cookie里
resp.addCookie(cookie);这个语句我们并没有写,也就是Session会自己打包进入Cookie,那么这个Cookie就是一个会话Cookie,是在内存存储的
会话对象会占用一定的资源,因此会话是不需要长久保留的
HTTP协议没有提供任何机制让服务器知道用户已经离开了,但是规定当一个用户在指定时间内没有请求产生,就去终止会话,这称为会话超时
这个时间默认30分钟
可以在web.xml内修改
- <session-conflg>
- <session-time>
- 10
- </session-time>
- </session-conflg>
元素内指定以分钟为单位的默认超时时间,如果值<=0,表示永不会过期