探索Cookie和Session

前言:本文章是Java Web后端技术系列的第五篇,主要介绍Tomcat服务器,接下来将持续更新,感兴趣的小伙伴欢迎持续关注。因为我也是刚接触Java web方面的知识,尚有许多不足,如有错误欢迎指正!

会话

B/S架构中:从浏览器第一次给服务器发送请求时,建立会话;直到有一方断开,会话结束。
一次会话包含多次请求响应。
HTTP协议是无状态协议,同一个会话中的连续多个请求是互相独立的,彼此互不了解。
会话技术就是存储浏览器和服务器之间的通信数据的。
客户端会话技术:cookie
服务器会话技术:session

Cookie

介绍

Cookie作用:在一次会话的多次请求之间共享数据,将数据保存到客户端(浏览器)

特点

  1. cookie存储数据都在客户端(浏览器)
  2. cookie的存储数据只能是字符串
  3. cookie单个大小不能超过4KB
  4. cookie存储的数据不太安全
  5. 只能保存字符串信息

相关API

  1. 设置数据到cookie中
    创建cookie对象,设置数据 value
    Cookie cookie = new Cookie(String name,String value);
    通过response,响应(返回)cookie
    response.addCookie(cookie);
  2. 从cookie中获取数据
    通过request对象,接收cookie数组
    Cookie[] cookies = request.getCookies();
    遍历数组

Cookie原理

服务器端调用 addCookie 函数,会在响应头中加入 Set-Cookie 字段,将cookie的数据传给浏览器
在这里插入图片描述
浏览器拿到响应头后把信息存到本地cookie,发送请求的时候会把本地cookie也发给服务器
在这里插入图片描述
服务器通过 getCookies() 方法拿到浏览器传来的数据。

使用

基本使用

需求:写两个servlet类,一个在浏览器的cookie中添加数据,一个读取浏览器cookie的数据

package cookiedemo.start;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Author: ChenJialian
 * @Description: cookie入门案例
 * @Date: Create in 22:51 2020/9/19
 */
public class startDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie c = new Cookie("name","jack");
        resp.addCookie(c);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}


package cookiedemo.start;

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;

/**
 * @Author: ChenJialian
 * @Description: cookie入门案例
 * @Date: Create in 22:53 2020/9/19
 */
@WebServlet("/startDemo2")
public class startDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cs = req.getCookies();
        if(null!=cs){
            for(Cookie c:cs){
            System.out.println(c.getName());
                System.out.println(c.getValue());
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

服务器发送多个Cookie

@WebServlet("/MultipleCookie")
public class MultipleCookie extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse
            response) throws ServletException, IOException {
        this.doPost(request, response);
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse
            response) throws ServletException, IOException {
// 1. 创建多个cookie对象
        Cookie cookie1 = new Cookie("name","lucy");
        Cookie cookie2 = new Cookie("age","18");
// 2. 通过response响应多个
        response.addCookie(cookie1);
        response.addCookie(cookie2);
    }
}

Cookie在浏览器保存时间(重点)

  • 默认情况下
    浏览器关闭(会话结束),cookie销毁(内存)
  • 设置cookie的存活时间
    cookie.setMaxAge(int second); – 单位是秒
    正数:指定存活时间,持久化浏览器的磁盘中,到期后自动销毁
    负数:默认浏览器关闭,cookie销毁
    零:立即销毁(自杀)
@WebServlet("/MaxAgeCookie")
public class MaxAgeCookie extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse
            response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse
            response) throws ServletException, IOException {
        // 1.创建cookie对象
        Cookie cookie = new Cookie("product", "xiaomi10");
        // 2.设置cookie存活时间
        // cookie.setMaxAge(-1); // 默认值,浏览器关闭自动销毁
        // cookie.setMaxAge(60);// 存活60秒,到期自动销毁
        cookie.setMaxAge(0); // 立即销毁...
        //3. response响应cookie
        response.addCookie(cookie);
    }
}

Cookie存储中文

  • tomcat8之前的版本,不支持中文
    • 使用URLEncoder编码、URLDecoder解码实现中文存储
  • tomcat8以后的版本,支持中文
@WebServlet("/EncodeCookie")
public class EncodeCookie extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse
            response) throws ServletException, IOException {
        this.doPost(request, response);
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse
            response) throws ServletException, IOException {
        String product = "中国话";
        product= URLEncoder.encode(product, "UTF-8");
		// 1.创建cookie对象
        Cookie cookie = new Cookie("product", product);
		// 2.response响应cookie
        response.addCookie(cookie);
    }
}

@WebServlet("/DecodeCookie")
public class DecodeCookie extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cs = req.getCookies();
        if(null!=cs){
            for(Cookie c:cs){
            	System.out.println(c.getName());
            	String value = c.getValue();
            	value = URLDecoder.decode(value,"UTF-8");
                System.out.println(value);
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

Session

介绍

使用Cookie问题

  1. 最多存储4K字符串
  2. 存储数据不太安全
    session作用:在一次会话的多次请求之间共享数据,将数据保存到服务器端

session工作流程如下
session工作流程

HttpSession域对象

方法

  1. 存储数据
    void setAttribute(String name,Object value)
  2. 获取数据
    Object getAttribute(String name)
  3. 删除数据
    void removeAttribute(String name)
    使用步骤
  4. 将数据存储到session中
    1.通过rquest对象,获取session对象
    HttpSession session = request.getSession();
    2.操作session的API,存储数据
    session.setAttribute("username","哈哈,呵呵");
  5. 从session中获取数据
    1.通过rquest对象,获取session对象
    HttpSession session = request.getSession();
    2.操作session的API,获取数据
    session.getAttribute("username");

生命周期

  • 何时创建
    用户第一次调用request.getSession()方法时创建,而不是创建会话时就创建
  • 何时销毁
    • 服务器非正常关闭。如果是正常关闭,会序列化后存储,而不是销毁
    • 非活跃状态30分钟后:即浏览器完全不操作页面
      • tomcat进行配置 /tocmat安装目录/conf/web.xml
        在这里插入图片描述
      • 也可以项目的web.xml文件中按照上面的格式设置
    • 调用session.invalidate();自杀
  • 作用范围
    • 一次会话中,多次请求之间
    • 注意:每一个浏览器跟服务器都是独立的会话

使用

基本使用

一个servlet将数据存入session,另一个取出并打印。

package com.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @Author: ChenJialian
 * @Description:
 * @Date: Create in 23:45 2020/9/19
 */
public class SetSession extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession hs = req.getSession();
        hs.setAttribute("username","Lee");
        System.out.println("存入session");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

package com.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;

/**
 * @Author: ChenJialian
 * @Description:
 * @Date: Create in 23:45 2020/9/19
 */
@WebServlet("/GetSession")
public class GetSession extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession hs = req.getSession();
        String str = (String)hs.getAttribute("username");
        resp.getWriter().println(str);
        resp.getWriter().write(str);
        System.out.println("取出session"+str);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

Session原理

req.getSession()的判断:

  • 如果用户是第一次访问(没有携带JSESSIONID),则创建session对象,生成编号并返回
  • 如果不是第一次访问,则查找JSESSIONID对应的session对象,如果找不到就创建。
    在这里插入图片描述
    验证:
    SetSession中
    在这里插入图片描述
    GetSession中
    在这里插入图片描述

三大域对象总结

经过上一篇文章和这篇文章的学习,我们了解了HTTPServletRequestServletContextHttpSession这三个域对象,下面对它们进行一些总结。

通用方法

设置数据
void setAttribute(String name, Object o)
获取数据
Object getAttribute(String name)
删除数据
void removeAttribute(String name)

生命周期

ServletContext域对象

  • 何时创建
    服务器正常启动,项目加载时,创建
  • 何时销毁
    服务器关闭或项目卸载时,销毁
  • 作用范围
    整个web项目(共享数据)

HttpSession域对象

  • 何时创建
    用户第一次调用request.getSession()方法时,创建
  • 何时销毁
    服务器非正常关闭
    未活跃状态30分钟
    自杀
  • 作用范围
    一次会话中,多次请求间(共享数据)

HttpServletRequest域对象

  • 何时创建
    用户发送请求时,创建
  • 何时销毁
    服务器做出响应后,销毁
  • 作用范围
    一次请求中,多次转发间(共享数据)

总结

  • 使用原则:能用小的不用大的,最小的是HttpServletRequest
  • 常用的场景:
    • request:一次查询的结果(servlet转发jsp)
    • session:存放当前会话的私有数据
      • 用户登录状态
      • 验证码
      • 购物车
    • servletContext:若需要所有的servlet都能访问到,才使用这个域对象
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值