Cookie & Session

Github:cookie&session

一. 会话技术

1. 定义

  1. 一次会话中包含多次请求和响应。
  2. 一次会话:浏览器第一次给服务器资源发送请求时,会话建立,直到有一方断开为止。

2. 功能

HTTP 是无状态的,每次请求之间相互独立,不能交换数据。

在一次会话的范围内(多次请求之间)共享数据。

3. 方式

  1. 客户端会话技术:Cookie
  2. 服务器端会话技术:Session

二. Cookie

1. 概念

客户端会话技术,将数据保存到客户端。

2. 使用

  1. 创建 Cookie 对象,绑定数据:new Cookie(String name, String value)
  2. 发送 Cookie 对象:response.addCookie(Cookie cookie)
  3. 获取 Cookie 对象,获得数据:Cookie[] request.getCookies()
@WebServlet("/cookieDemo1")
public class CookieDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 创建 Cookie 对象,绑定数据
        Cookie cookie = new Cookie("msg", "hello");
        // 2. 发送 Cookie 对象
        response.addCookie(cookie);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
@WebServlet("/cookieDemo2")
public class CookieDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 3. 获取 Cookie 对象,获得数据
        Cookie[] cookies = request.getCookies();
        if(cookies != null) {
            for (Cookie cookie : cookies) {
                String name = cookie.getName();
                String value = cookie.getValue();
                System.out.println(name + "=" + value);
            }
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

3. 实现原理

基于响应头 Set-Cookie 和请求头 Cookie 实现。
Cookie的实现原理

4. 细节

1.一次可以发送多个 Cookie

  • 创建多个 Cookie 对象,调用 addCookie() 分别添加至 response 发送。
  • 如果对同一个 Cookie 对象多次赋值,其值会被覆盖。
@WebServlet("/cookieDemo3")
public class CookieDemo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 创建 Cookie 对象,绑定数据
        Cookie cookie1 = new Cookie("msg", "hello");
        Cookie cookie2 = new Cookie("name", "hjplz");
        // 2. 发送 Cookie 对象
        response.addCookie(cookie1);
        response.addCookie(cookie2);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

2.Cookie 在浏览器中的保存时间

  • 在默认情况下,关闭浏览器后,Cookie 数据被销毁。
  • 持久化存储:setMaxAge(int expiry)
    • 正数:将 Cookie 数据写到硬盘的文件中,存活时间为 expiry 秒。
    • 负数:默认情况
    • 0:删除 Cookie 信息
@WebServlet("/cookieDemo4")
public class CookieDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 创建 Cookie 对象,绑定数据
        Cookie cookie = new Cookie("msg", "setMaxAge");
        // 2. 设置 Cookie 的存活时间
        cookie.setMaxAge(30); // 将 Cookie 数据写到硬盘的文件中,存活时间为30秒
        // cookie.setMaxAge(-1); // 默认情况
        // cookie.setMaxAge(0); // 删除 Cookie 信息
        // 3. 发送 Cookie 对象
        response.addCookie(cookie);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

3.Cookie 存储中文

  • 在 Tomcat 8 之前,不能在 Cookie 中直接存储中文数据,需要将中文数据转码,一般采用 URL 编码(%E3)。
  • 在 Tomcat 8 之后,在 Cookie 中可以直接存储中文数据,但不支持特殊字符,建议使用 URL 编码存储 & 解析特殊字符。
@WebServlet("/cookieDemo5")
public class CookieDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 创建 Cookie 对象,绑定数据
        Cookie cookie = new Cookie("msg", "你好");
        // 2. 发送 Cookie 对象
        response.addCookie(cookie);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

4.Cookie 共享问题

  • 在一个 Tomcat 服务器中部署的多个 web 项目之间共享 Cookie 信息
    • 在默认情况下,不能共享 Cookie 信息。
    • 通过 setPath(String path) 设置 Cookie 的共享范围为 “/”,默认值是当前的虚拟目录(Context Path)。
@WebServlet("/cookieDemo6")
public class CookieDemo6 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 创建 Cookie 对象,绑定数据
        Cookie cookie = new Cookie("msg", "你好");
        // 2. 设置 path,让当前服务器下部署的所有项目共享 Cookie 信息
        cookie.setPath("/");
        // 3. 发送 Cookie 对象
        response.addCookie(cookie);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
  • 在不同的 Tomcat 服务器中部署的 web 项目之间共享 Cookie 信息
    • 通过 setDomain(String path) 设置一级域名相同,来实现在多个服务器之间共享 Cookie 信息。e.g. setDomain(".baidu.com") ,tieba.baidu.com 和 news.baidu.com 之间可以共享 Cookie 信息。

5. 特点 & 作用

1.特点

  • 在客户端浏览器存储 Cookie 数据
  • 浏览器对于单个 Cookie 的大小有限制(4KB),对于同一个域名下的总 Cookie数量有限制(20个)。

2.作用

  • 存储少量 & 不太敏感的数据
  • 在用户不登录的情况下,完成服务器对客户端的身份识别。

6. 案例:记住上一次访问时间

JavaWeb-Demo3:记住上一次访问时间

三. Session

1. 概念

服务器端会话技术,将数据保存到服务器端的 HttpSession 对象中。

2. 使用

1.获取 HttpSession 对象:HttpSession session = request.getSession();

2.使用 HttpSession 对象

  • Object getAttribute(String name)
  • void setAttribute(String name, Object value)
  • void removeAttribute(String name)
@WebServlet("/sessionDemo1")
public class SessionDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 获取 Session
        HttpSession session = request.getSession();
        // 2. 存储数据
        session.setAttribute("msg", "Hello Session!");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
@WebServlet("/sessionDemo2")
public class SessionDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 3. 获取存在 Session 中的数据并打印
        System.out.println(request.getSession().getAttribute("msg"));
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

3. 实现原理

Session 的实现依赖于 Cookie。
Session实现原理

4. 细节

1.当客户端关闭,服务器不关闭,两次获取的 Session 在默认情况下不是同一个(因为不是同一个会话)。

  • 如果要持久化保存 Session, 可以设置 JSESSIONID 的 Cookie。
    @WebServlet("/sessionDemo3")
    public class SessionDemo3 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // 获取 Session
            HttpSession session = request.getSession();
            // 客户端关闭 1 min 之内,能获得相同的 Session
            Cookie cookie = new Cookie("JSESSIONID", session.getId());
            cookie.setMaxAge(60 * 60); // 1 min
            response.addCookie(cookie);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request, response);
        }
    }
    

2.当客户端不关闭,服务器关闭,两次获取的 Session 在默认情况下不是同一个。为了确保数据不丢失,Tomcat 自动完成以下工作:

  • Session 的钝化:在服务器正常关闭之前,将 Session 对象序列化到硬盘上。
  • Session 的活化:在服务器启动后,将 Session 文件转化为内存中的 Session 对象。

3.Session 的失效时间:默认为 30 mins

  • 服务器关闭

  • Session 对象调用 invalidate()

  • 修改配置文件 web.xml,指定失效时间。

    <session-config>
    		<session-timeout>30</session-timeout>
    </session-config>
    

5. 特点

1.在服务器端存储一次会话的多次请求的数据。

2.可以存储任意类型、任意大小的数据。

3.与 Cookie 的区别

  • Session 存储数据在服务器端,Cookie 存储数据在客户端。
  • Session 没有数据大小限制,Cookie 有。
  • Session 数据安全,Cookie 相对不安全。

6. 案例:验证码

JavaWeb-Demo4:验证码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值