Cookie 和 Session

Cookie

1、什么是 Cookie

  1. Cookie 翻译过来是饼干的意思
  2. Cookie 是服务器通知客户端保存键值对的一种技术
  3. 客户端有了 Cookie后,每次请求都发送给服务器
  4. 每个 Cookie 的大小不能超过 4k

构造器:
Cookie(String name, String value)
里面存放的是键值对式的

Cookie 对象有两个方法来获取键值对的数据
cookie.getName() 方法返回 Cookie 的 key(名)
cookie.getValue() 方法返回 Cookie 的 value

2、创建 Cookie(用response)

在这里插入图片描述
Servlet 程序中的代码:

protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
	//1 创建 Cookie 对象
	Cookie cookie = new Cookie("key4", "value4");
	//2 通知客户端保存 Cookie
	resp.addCookie(cookie);
	//1 创建 Cookie 对象
	Cookie cookie1 = new Cookie("key5", "value5");
	//2 通知客户端保存 Cookie
	resp.addCookie(cookie1);
	// 客户端输出
	resp.getWriter().write("Cookie 创建成功");
}

设置超链接按钮的 jsp 页面:
使用相对路径就要先设置

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

    <%--动态包含,head 中 css样式、jquery文件、base标签--%>
    <jsp:include page="/pages/common/css_base_jquery.jsp"></jsp:include>

<a href="client/clientServlet?methodName=createCookie">创建饼干对象</a>

在这里插入图片描述

servlet 通过使用 HttpServletResponse#addCookie 方法将 cookie 发送到浏览器,该方法将字段添加到 HTTP 响应头,以便一次一个地将 cookie 发送到浏览器

浏览器接收到响应之后,发现了 响应头信息,就会根据 Cookie 对象的 key 值查询,如果已经有了这个 Cookie 对象,就修改 value 值若没有这个对象,就创建 Cookie 对象

在这里插入图片描述

注意:

  1. response.addCookie(cookie1);一次只可以传送一个 cookie 对象发送到浏览器
  2. 是通过将字段添加到 HTTP 响应头来进行传输

3、服务器如何获取 Cookie(用request)

服务器获取客户端的 Cookie 只需要一行代码:

request.getCookies()返回的是数组 Cookie[ ]

在这里插入图片描述
因为获取 Cookie 的方法返回的是一个 Cookie[ ] 的数组,所以如果要查询指定的 Cookie 对象,只有在遍历数组的时候进行判断

一般情况都把这段代码封装为一个 Utils 类,作为工具类

Cookie 的工具类:

public class CookieUtils {
    /**
     * 查找指定名称的 Cookie 对象
     */
    public static Cookie findCookie(String name, Cookie[] cookies) {
        if (name == null || cookies == null || cookies.length == 0) {
            return null;
        }
        //遍历  Cookie 数组
        for (Cookie cookie : cookies) {
        	// 如果  Cookie 对象的 key 值是我们需要的,就返回 Cookie 对象
            if (name.equals(cookie.getName())) {
                return cookie;
            }
        }
        return null;
    }
}

工具类使用

    protected void getCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1 获取浏览器的饼干对象
        Cookie[] cookies = request.getCookies();
        //2 使用工具类
        Cookie cookiekey1 = CookieUtils.findCookie("key1", cookies);
        // 如果找到了
        if(cookiekey1 != null){
            response.getWriter().write("Cookie[" + cookiekey1.getName() + "=" + cookiekey1.getValue() + "] <br/>");
        }
    }

在这里插入图片描述

4、Cookie 值的修改

方案一:
1、先创建一个要修改的同名(指的就是 key)的 Cookie 对象
2、在构造器,同时赋于新的 Cookie 值。
3、调用 response.addCookie( Cookie )

因为如果传递给浏览器的 Cookie 对象的 key 值已经存在,浏览器就会将新的 value 值赋值给 Cookie 对象
如果 key 值没有存在,就会创建 Cookie 对象

方案二:
1、先查找到需要修改的 Cookie 对象
2、调用 setValue()方法赋于新的 Cookie 值。
3、调用 response.addCookie()通知客户端保存修改

	// 1、先查找到需要修改的 Cookie 对象
	Cookie cookie = CookieUtils.findCookie("key2", req.getCookies());
	// 若找到了这个 Cookie 对象
	if (cookie != null) {
		// 2、调用 setValue()方法赋于新的 Cookie 值。
		cookie.setValue("newValue2");
		// 3、调用 response.addCookie()通知客户端保存修改
		resp.addCookie(cookie);
	}

5、浏览器查看 Cookie

5.1、谷歌浏览器如何查看 Cookie

在这里插入图片描述

5.2、火狐浏览器如何查看 Cookie

通过右击来选择删除等操作
在这里插入图片描述

6、Cookie 生命控制

Cookie 的生命控制指的是如何管理 Cookie 什么时候被销毁(删除)

  • cookie.setMaxAge(int seconds)
    • 正数,表示在指定的秒数后过期
    • 负数,表示浏览器一关,Cookie 就会被删除 (默认值是-1)
    • 零,表示马上删除 Cookie

默认情况都是 关闭浏览器, Cookie 对象就会被销毁

/**
* 设置存活 1 个小时的 Cooie
*/
protected void life3600(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
	Cookie cookie = new Cookie("life3600", "life3600");
	cookie.setMaxAge(60 * 60); // 设置 Cookie 一小时之后被删除。无效
	resp.addCookie(cookie);
	resp.getWriter().write("已经创建了一个存活一小时的 Cookie");
}
/**
* 马上删除一个 Cookie
*/
protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
	// 先找到你要删除的 Cookie 对象
	Cookie cookie = CookieUtils.findCookie("key4", req.getCookies());
	if (cookie != null) {
		// 调用 setMaxAge(0);
		cookie.setMaxAge(0); // 表示马上删除,都不需要等待浏览器关闭
		// 调用 response.addCookie(cookie);
		resp.addCookie(cookie);
		resp.getWriter().write("key4 的 Cookie 已经被删除");
	}
}
/**
* 默认的会话级别的 Cookie
*/
protected void defaultLife(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
	Cookie cookie = new Cookie("defalutLife","defaultLife");
	cookie.setMaxAge(-1);//设置存活时间
	resp.addCookie(cookie);
}

7、Cookie 有效路径 Path 的设置

Cookie 的 path 属性可以有效的 过滤哪些 Cookie 可以发送给服务器,哪些不发

path 属性是通过请求的地址来进行有效的过滤

比如,有如下两个带有 Path 路径的 Cookie 对象:

CookieA path=/工程路径
CookieB path=/工程路径/abc

当请求地址如下:

  • http://ip:port/工程路径/a.html
    CookieA 发送
    CookieB 不发送
  • http://ip:port/工程路径/abc/a.html
    CookieA 发送
    CookieB 发送

如果没有设置 Path 路径,默认的路径为/工程路径

注意:
默认的路径为/工程路径的前提是 servlet 程序设置的 url 路径只有一个斜杠

一个斜杠的时候,饼干对象的默认 path 路径才会是 工程路径

若 url 地址为 / abab / loginServlet ,那么饼干对象的默认 path 路径就是 工程路径 / abab

那么在访问登录页面 工程路径 / login.jsp 的时候,当前页面就没有饼干对象,因为 path 路径限制了这个地址没有饼干对象

protected void testPath(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
	Cookie cookie = new Cookie("path1", "path1");
	// getContextPath() ===>>>> 得到工程路径
	cookie.setPath( req.getContextPath() + "/abc" ); // ===>>>> /工程路径/abc
	resp.addCookie(cookie);
	
	//未设置 path 路径,便默认为工程路径,但若 servlet 程序路径有多个斜杠,就是 servlet 程序路径的最后一个斜杠
    Cookie cookie2 = new Cookie("path2", "path2");
    response.addCookie(cookie2);
	
	resp.getWriter().write("创建了一个带有 Path 路径的 Cookie");
}

在这里插入图片描述
在这里插入图片描述

8、练习—免输入用户名登录

在这里插入图片描述

将用户输入的用户名封装进 Cookie 对象,设置有效时间为 7 天

注意,只有第一次用户登录成功之后,浏览器才会保存用户名

在这里插入图片描述
饼干对象成功创建之后,就算关闭浏览器,然后再访问登录页面,也还会存在 用户名
在这里插入图片描述
注意:
这里编写的 servlet 程序最好设置的 url 路径只有一个斜杠

一个斜杠的时候,饼干对象的默认 path 路径才会是 工程路径

若 url 地址为 / abab / loginServlet ,那么饼干对象的默认 path 路径就是 工程路径 / abab

那么在访问登录页面 工程路径 / login.jsp 的时候,当前页面就没有饼干对象,因为 path 路径限制了这个地址没有饼干对象

    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.atguigu.web.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/loginServlet</url-pattern>
    </servlet-mapping>

servlet 程序

public class LoginServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取请求参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //判断是否登陆成功
        if("admin".equalsIgnoreCase(username) && "123123".equalsIgnoreCase(password)){
            Cookie cookie = new Cookie("username", username);
            cookie.setMaxAge(60*60*24*7);
            response.addCookie(cookie);
            System.out.println("登陆成功");
        }else {
            System.out.println("登陆失败");
        }
    }
}

登录页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<body>
<form action="http://localhost:8080/book02/loginServlet" method="get">
    <input type="hidden" name="methodName" value="createCookie"/>
    用户名:<input type="text" name="username" value="${cookie.username.value}"/>
    密码:<input type="password" name="password"/>
    <input type="submit"/>
</form>
</body>

Session

1、什么是 Session 会话?

  1. Session 就一个接口(HttpSession)
  2. Session 就是会话。它是用来维护一个客户端和服务器之间关联的一种技术
  3. 每个客户端都有自己的一个 Session 会话
  4. Session 会话中,我们经常用来保存用户登录之后的信息。

2、如何创建 Session 和获取( id 是否为新)

  1. 如何创建和获取 Session?使用的都是一个方法

request.getSession()
当第一次调用的时候,就会创建 Session 会话对象
而之后调用,就会获取前面创建好的 Session 会话对象

  1. 如何判断 Session 会话对象是否为新?

isNew();
判断到底是不是刚创建出来的(新的)
true :表示是刚创建出来的
false :表示是获取之前已经创建的

  1. 判断是否为新的原理就是通过查找 ID 值

每个会话都有一个身份证号,也就是 ID 值,而且这个 ID 是唯一的

getId() 可以得到 Session 的会话 id 值

session.html 页面代码:

<base href="http://localhost:8080/untitled/">
<a href="sessionServlet?methodName=getSession" target="target">Session的创建和获取(id号、是否为新创建)</a>

SessionServlet 代码:

public class SessionServlet extends BaseServlet {
    protected void getSession(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        String id = session.getId();
        response.getWriter().write(session + "<br/>");
        response.getWriter().write("Session的id" + id + "<br/>");
        response.getWriter().write("Session的创建和获取");
    }
}

在这里插入图片描述

3、Session 域数据的存取

setAttribute(String key, String value);设置 Session 域数据

getAttribute( String key );获取 Session 域数据

/**
 1. 往 Session 中保存数据
*/
protected void setAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
	req.getSession().setAttribute("key1", "value1");
	resp.getWriter().write("已经往 Session 中保存了数据");
}
/**
 2. 获取 Session 域中的数据
*/
protected void getAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
	Object attribute = req.getSession().getAttribute("key1");
	resp.getWriter().write("从 Session 中获取出 key1 的数据是:" + attribute);
}

4、Session 生命周期控制

  1. 设置超时时间

注意:
这里的时长是指 Session 对象停止活动时长,也就是说,只要你的手速过快, Session 对象就永远不会超时

public void setMaxInactiveInterval(int interval);
设置 Session 的超时时间(以秒为单位),超过指定的时长,Session 就会被销毁

值为正数的时候,设定 Session 的超时时长
负数表示永不超时(极少使用)

public int getMaxInactiveInterval()
获取 Session 的超时时间
public void invalidate()
让当前 Session 会话马上超时无效,其原理就是后台将超时的时间设置为 1970 年,所以一旦调用,自然就立即失效了

  1. Session 默认的超时时长是多少?

Session 默认的超时时间长为 30 分钟

因为在 Tomcat 服务器的配置文件 web.xml中默认有以下的配置,它就表示配置了当前 Tomcat 服务器下所有的 Session 超时配置默认时长为:30 分钟。

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

如果说,你希望你的 web 工程,默认的 Session 的超时时长为其他时长,你可以在你自己的 web.xml 配置文件中做以上相同的配置。就可以修改你的 web 工程中所有 Session 的默认超时时长

<!--表示当前 web 工程中创建出来的所有 Session 默认是 20 分钟超时时长-->
<session-config>
	<session-timeout>20</session-timeout>
</session-config>
  1. 修改个别 Session 的超时时长

如果你想只修改个别 Session 的超时时长,就可以使用上面的 API,setMaxInactiveInterval(int interval) 来进行单独的设置

session.setMaxInactiveInterval(int interval)
单独设置超时时长

  1. Session 超时的概念介绍

在这里插入图片描述
Session 马上被超时示例:

protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
	// 先获取 Session 对象
	HttpSession session = req.getSession();
	// 让 Session 会话马上超时
	session.invalidate();
	
	resp.getWriter().write("Session 已经设置为超时(无效)");
}

5、浏览器和 Session 之间关联的技术内幕

Session 技术,底层其实是基于 Cookie 技术来实现的

通过 Cookie 保存的 Session 的 id,当浏览器关闭,Cookie 没了 ,浏览器自然也就找不到那个 Session 了,就相当于 Session 没了

Cookie 是存在客户端的,为了发送一些不需要用户操作的报文的,而 Session 是存在于服务器端的,用来保持用户登录的

由于 http 是无状态的,没法保存信息,但每次浏览器请求数据时,可能需要携带大量重复信息,就会让 Cookie 是客户端用于记录,Session 用于服务端记录
在这里插入图片描述
为什么明明 Session 还没有超时,但是关闭浏览器 Session就无效了?

因为 Cookie 的存活范围默认是 Session,是一个会话,关闭了浏览器,Cookie 就没了,SessionID 就没了,Session 自然就没了

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值