前提
提出问题
- HTTP协议是一种无状态协议,WEB服务器本身不能识别出哪些请求是同一个浏览器发出的,浏览器的每一次请求都是完全孤立的
- 即使HTTP1.1支持持续连接,但当用户有一段时间没有提交请求,连接也会关闭
- 怎么才能实现网上商店中的购物车呢:某个用户从网站的登录页面登入后,再进入购物页面购物时,负责处理购物请求的服务器程序必须知道处理上一次请求的程序所得到的用户信息。
- 作为web服务器,必须能够采用一种机制来唯一地标识一个用户,同时记录该用户的状态会话和会话状态
- WEB应用中的会话是指一个客户端浏览器与WEB服务器之间连续发生的一系列请求和响应过程
- WEB应用的会话状态是指WEB服务器与浏览器在会话过程中产生的状态信息,借助会话状态,WEB服务器能够把属于同一会话中的一系列的请求和响应过程关联起来
如何实现有状态的会话
- WEB服务器端程序要能从大量的请求信息中区分出哪些请求信息属于同一个会话,即能识别出来自同一个浏览器的访问请求,这需要浏览器对其发出的每个请求信息都进行标识:属于同一个会话中的请求消息都附带同样的标识号,而属于不同会话的请求消息总是附带不同的标识号,这个标识号就称之为会话ID(SessionID)。
- 在Servlet规范中,常用Cookie和Session两种机制完成会话跟踪
Cookie机制
采用的是在客户端保持HTTP状态信息的方案。
Cookie是在浏览器访问WEB服务器的某个资源时,由WEB服务器在HTTP响应消息头中附带传送给浏览器一个小文本文件。
一旦WEB浏览器保存了某个Cookie,那么它在以后每次访问该WEB服务器时,都会在HTTP请求头中将这个Cookie回传给WEB服务器。
底层的实现原理:WEB服务器通过在HTTP响应消息中增加Set-Cookie响应头字段将Cookie消息发送给浏览器,浏览器则通过在HTTP请求消息中增加Cookie请求头字段将Cookie回传给WEB服务器。
一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
Cookie的传送过程示意图
在Servl程序中使用Cookie
Servlet API中提供了一个javax.servlet.htp.Cookie类来封装Cookie信息,它包含有生成Cookie信息和提取Cookie信息的各个属性的方法。
Cookie类的方法:
- 构造方法:public Cookie (String name , String value)
- getName方法
- setValue与getValue方法
- setMaxAge与getMaxAge方法
- setPath与getPath方法
HttpServletResponse接口中定义了一个addCookie方法,它用于在发送给浏览器的HTTP响应消息中增加了一个Set-Cookie响应头字段。
HttpServletRequest接口定义了一个getCookies方法,它用于从HTTP请求信息的Cookie请求头字段中读取所有的Cookie项
package org.lanqiao.cookie.demo;
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;
import java.io.PrintWriter;
@WebServlet("/cookieServlet")
public class CookieServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
//1 创建cookie
Cookie cookie = new Cookie("name","lanqiao");
//2 设置cookie的最大有效期
cookie.setMaxAge(60*60*24);
//3 将cookie回传给客户端
response.addCookie(cookie);
//4 获取cookile 通过request的getCookies() 获取到的是当前请求中的所有的cookie 因此 这里得到的是一个数组
Cookie[] cookies = request.getCookies();
// 5 对获取的cookie数组进行遍历
for(Cookie cook: cookies){
//6 获取每个cookie的名称
// String cookName = cook.getName();
//7 判断获取到的cookie的名称是否是我们所关心的cookie i如果是 则 获取当前cookie的值
//if(cookName.equals("name")){
out.print(cook.getName() +"-------"+cook.getValue());
// }
}
}
}
Cookie的发送
1、创建Cookie对象
2、设置最大时效
3、将Cookie放入到HTTP响应报头
如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie;存储在浏览器的内存中,用户退出浏览器之后被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
发送cookie需要使用HttpServletResponse的addCookie方法,将cookie插入到一个Set-Cookie HTTP响应报头中。由于这个方法并不修改任何之前指定的Set-Cookie报头,而是创建新的报头,因此将这个方法称为是addCookie,而非setCookie。
Cookie的读取
1、调用request.getCookies。要获取浏览器发送来的cookie,需要调用HttpServle