会话 session 和 cookie 详解

1/Cookie 概述

一、什么叫 Cookie

Cookie 翻译成中文是小甜点,小饼干的意思。在 HTTP中它表示服务器送给客户端浏览器的小甜点。其实 Cookie 就是一个健和一个值构成的,随着服务器的响应发送给客户端浏览器。然后客户端浏览器会把 Cookie 保存起来,当下一次在访问服务器时把 Cookie 再发送给服务器。

二、Cookie 规范

你大可以放心,Cookie 不会占满你的硬盘。因为一个 Cookie 最多只有 4KB,并且浏览器最多可以保存 300 个 Cookie。当然,在浏览器大战的今天,一些浏览器为了打败对手,可能对 Cookie 规范“扩展”了一些,例如每个 Cookie 的大小为 8KB ,最多可保存 500 个 Cookie 等!但也不会出现把你硬盘占满的可能!

不同的浏览器之间不能共享 Cookie!!!

三、Cookie 的作用

Cookie 的作用可大了,但无论怎么夸大 Cookie 的作用都离不开“跟踪客户端状态”这句话。我们知道 Cookie 是服务器保存在客户端的信息,然后客户端会在下次请求时把 Cookie 在还给服务器,这样服务器就可以通过信息来识别客户端了。

2/Cookie 的示例

一、保存 Cookie 到客户端

这是响应工作的一部分,所以这个方法是 response 对象的。并且 Cookie 是 HTTP 协议中的内容,所以保存 Cookie 是 HttpServletResponse 类的方法。

void addCookie(Cookie c):添加 Cookie 对象到当前 response 对象中,这个方法可以被调用多次,从而完成添加多个 Cookie 对象到 response 中。

《《《

public class AServlet extends HttpServlet{

public void doGet(HttpServletRequest request,HttpservletResponse response){

Cookie c = new Cookie("name","zhangsan");

response.addCookie(c);

}

}

》》》

使用浏览器访问 http://localhost/day06_03/AServlet,然后通过 HttpWatch 查看响应头信息中是否存在 Set-Cookie 这个头信息。

当再交方法 Http://localhost/day07-03/AServlet 时,查看请求头信息中是否存在 Cookie 这个头信息。当然也可以尝试访问 http://localhost/day07_03/BServlet 是否在请求中存在 Cookie 这个头信息。

图片【】【】

尝试访问 http://localhost/day07_03/BServlet,你可能会说,Servlet 不存在,没错,BServlet 是不存在,但我们只关心请求,而不关心响应。我们只需要看看在请求中是否存在 Cookie 这个头信息。你应该已经尝试过了,也看到了 Cookie 头信息。这说明不只是访问 AServlet 才会有 Cookie 请求头信息,而是只要访问这个 day07_03 就会有 Cookie 这个请求头。

Cookie 的大小是限的,浏览器最多可以保存 300 个 Cookie,一个 Cookie 最多只有 4KB,如果超出最大容量就会报如下错误。

图片【】【】

二、服务器读取 Cookie

我们现在已经可以保存 Cookie 到客户端了,但还没有学习让服务器如何读取 Cookie。

如果浏览器保存了 Cookie,那么会在下次请求时把 Cookie 放到请求头中发送给服务器,这是服务器需要在请求中读取 Cookie。既然是在请求中读取,那么当然是使用 request 对象来读取了。

HttpServletRequest:Cookie[] getCookie()

注意,它返回的是 Cookie 数组,而不是一个 Cookie 对象。如果请求中没有 Cookie,那么该方法返回 null。

《《《

Cookie[] cs = request.getCookies();

if(cs != null){

for(Cookie c : cs){

String str = c.getName() + ":" + c.getValue() + "<br/>";

response.getWriter().print(str);

}

}

》》》

3/Cookie 的生命周期

Cookie 会在客户端存活多久呢?这就是 Cookie 的生命了。默认情况下,Cookie 只在浏览器的内存中存活,也就是说,当你关闭浏览器后,Cookie 就会消失!

可以使用 Cookie#setMaxAge(int expiry)来设置 Cookie 的存活时间。参数 expiry 表示 Cookie 存活的秒数。

cookie.setMaxAge(60*60):表示 cookie 对象可存活 1 小时。就算关闭浏览器,就算重启客户端电脑,cookie 也会存活 1 小时。因为当 maxAge 大于 0 时,浏览器不仅会把 cookie 保存在浏览器内存中,还会把 cookie 保存到硬盘上。

cookie.setMaxAge(-1):cookie 的 maxAge 属性的默认值就是 -1 (其实只要是负数都是一个意思),表示只在浏览器内存中存活。一旦关闭浏览器窗口,那么 cookie 就会消失。

cookie.setMaxAge(0):cookie 被作废!表示 cookie 即不在内存中存活,也不在硬盘上存活,这样的 cookie 设置只有一个目的,那就是覆盖客户端原来的这个 cookie,使其作废。

4/浏览器管理 Cookie

5/Cookie 的路径

Cookie 还有一个 path 属性,可以通过 Cookie#setPath(String) 方法来设置。你可以使用 HttpWatch 查看响应中的 Set-Cookie 中是否存在路径。下面是通过 FireFox 查看 Cookie 信息。

【【图片】】

也就是说,就算你不设置 Cookie 的 Path,Cookie 也是有路径的。这个路径就是请求的路径。例如在请求 http://localhost/day07_03/AServlet 时,服务器响应了一个 Cookie 的默认路径就是 /day07_03/。

例如请求的路径是 http://localhost/day07_03/servlet/BServlet 时,服务器响应了一个 Cookie,那么这个 Cookie 的默认路径就是 /day07_03/servlet/。

【【【图片】】】

到现在我们还没说过 Cookie 的 path 有什么用,我们现在来聊聊 path 的作用。首先声明一点,path 不是指 Cookie 在客户端存放的路径!!!不同的浏览器存放 Cookie 的路径是不同的!!! 你不能通过 Cookie 的 Path 来指定 Cookie 文件的存放路径!!!

那么 Cookie 的 path 是干什么的呢?假设你在浏览器当前已经有了两个 Cookie:

c1:name=id;value=itcast; path=/day07_03/;

c2:name=name;value=qdmmy6;path=/day07_03/servlet/。

当访问 http://localhost/day07_03/* 时,请求头中会包含 c1,而不会包含 c2。

当访问 http://localhost/day07_03/servlet/*时,请求头中会包含 c1 和 c2。

也就是说,在访问子路径时,会包含其父路径的 Cookie,而在访问父路径时,不包含子路径的 Cookie。

请求的路径请求中包含的

/day07_03/

/day07_03/a/

Http://localhost/day07_03/a/b/c/MyServlet/day07_03/a/b/

/day07_03/a/b/c/

/day07_03/

http://localhost/day07_03/a/b/MyServlet/day07_03/a/

/day07_03/a/b/

http://localhost/day07_03/MyServlet/day07_03/

如果你想在 BServlet 中设置的 Cookie,在客户端访问 AServlet 时也包含在请求头中,那么就需要设置 BServlet 中的 Cookie 的 path。

c2.setPath("/day07_03/"):硬编码;

c2.setPath(request.getContextpath() + "/"):活编码。

这样就可以设置 Cookie 的路径,保存在访问 AServlet 时,也会包含 BServlet 中添加的 Cookie。

Cookie 的 SetPath 设置 Cookie 的路径,这个路径直接决定服务器的请求是否会从浏览器中加载某些 Cookie。

首先默认情况如果不设置 cookie 的 path,默认是 /项目名称/当前路径的上层地址如:请求路径: /cookie_demo/servlet/login, cookie 的路径:/cookie_demo/servlet。

如果我们设置 path,如果当前访问的路径包含了 cookie 的路径(当前访问路径在 cookie 路径基础上要比 cookie 的范围小)cookie 就会加载到 request 对象之中。

6/Cookie 中保存中文

Cookie 中保存中文,次要。

Cookie 中是不可以设置中文的,但可以使用 URLEncodor.encode() 方法编码后在存放到 Cookie 中。在获取 Cookie 时,需要先使用 URLDecoder.decode() 方法解码,在使用。

向客户端响应中添加 Cookie

《《《

String name = URLEncoder.encode("姓名", "UTF-8");

String value = URLEncoder.encode("张三", "UTF-8");

Cookie c = new Cookie(name, value);

c.setMaxAge(3600);

response.addCookie(c);

从客户端请求中获取 Cookie

response.setContentType("text/html; charset=utf-8");

Cookie[] cs = request.getCookies();

if(cs != null){

for(Cookie c : cs){

String name = URLDecoder.decode(c.getName(), "UTF-8");

String value = URLDecoder.decode(c.getValue(), "UTF-8");

String s = name + ":" + value + "<br/>";

response.getWriter().print(s);

}

}

》》》

7/Cookie 的禁用处理

默认情况下浏览器的 Cookie 是被启用的,但是其实我们是可以手动禁用 Cookie 的,强烈不建议禁用 Cookie。

【【图片】】

Cookie 一旦被禁用掉绝大多数互联网的网站都无法登录,这个跟我们后续要讲解的 Session 有关。那么我们如何通过程序来通过程序判断用户的浏览器上的 Cookie 是否被禁用了呢,其实很简单,我们可以通过刚刚添加的 Cookie,如果没有取到,说明 cookie 被禁用。

《《《

Cookie cookie = new Cookie("username", username);

resp.addCookie(cookie);

Cookie[] cookie = req.getCookies();

boolean isExsit = false;

for(Cookie ck : cookies){

String name = ck.getName();

if("username",equals(name)){

isExsit = true;

}

}

if(! isExsit){

System.out.println("cookie被禁用了");

}

》》》

8/Cookie 练习

使用 cookie 做一个自动登录的功能

9/HttpSession 概述

会话跟踪之 session

session 也是域对象之一,它的范围是在一个会话范围内有效。session 既然是域对象,那么当然就要有 getAttribute() 和 setAttribute() 系列方法了。

在一个会话内共享一个 session 对象,所以 session 中可以保存一个会话内的数据。例如当前用户的信息。

session 的范围大于request,可以在一个会话中多个请求之间共享数据。但 session 的范围小于 ServletContext(application),session 不能在多个用户之间共享数据。

目前所学过的域对象的作用范围:

ServletContext> HttpSession>HttpServletRequest

使用 request.getSession() 方法就可获取 Session 对象。

有了 Session,就不用使用 Cookie 来跟踪会话了! 但是 Session 不能像 Cookie 那样长命,一旦用户关闭浏览器窗口,那么 Session 就死掉了。

10/Session 原理(依赖 Cookie)

第一次访问客户端没有 sessionID

session池

浏览器———————————>服务器id:001

session 对象

【【图片】】

我们都知道 HTTP 是吴无状态协议,但是为什么 session 可以跟踪会话状态呢?没错,session 依赖 Cookie。

当客户端第一次访问服务器时,服务器会为客户端创建一个 session 对象,然后把 session 对象放到 session 池中,在响应时把 Session 通过 Cookie 响应给客户端。注意,只有在第一次访问时,服务器才会创建 session,给客户端响应 SessionID。从此以后就不会了!

当客户端再次访问服务器时,会在请求中带着 SessionId 给服务器,服务器通过 sessionId 到 session 池中找到 Session 对象,这就可以完成会话跟踪了。也就是说,服务器端保存的是 session 对象,而客户端只有 SessionId。每次访问都需要通过客户端的 SessionId 来匹配服务器端的 Session 对象!这样用户在 Session 中保存的数据就可以再次被使用了。

SessionId 是服务器通过 Cookie 发送给客户端浏览器的,这个 Cookie 的 MaxAge 为 -1,即只在浏览器内存中存在。如果你关闭所有浏览器窗口,那么这个 Cookie 就会消失了!

11/Session 失效

session 失效有如下几个原因:

session.invalidate() 方法注销 Session

session 超时

《《《

<session-config>

<!-- session 的超时时间,以分钟为单位 -->

<session-timeout>1<session-timeout>

</session-config>

》》》

cookie 被禁用

12/HttpSession 练习1:登录

做一个用户登录的功能要在 session 中保存用户的信息,并且能够使用 Cookie 自动登录。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值