1. 现有问题
- HTTP协议是无状态的,不能保存每次提交的信息
- 如果用户发来一个新的请求,服务器无法知道它是否与上次的请求有联系
- 对于那些需要多次提交数据才能完成的web操作,比如登陆来说就成问题。
2.概念
- 将浏览器与web服务器多次交互当做一个整体来处理,并将多次交互所产生的数据(即状态)保存下来
3.状态管理分类
- 客户端状态管理技术:将状态保存在客户端,代表性的是Cookie技术
- 服务器状态管理技术:将状态保存在服务端,代表性的是session技术(服务器传递sessionID时需要使用cookie的方式)和appliaction
4.Cookie的使用
4.1 什么是Cookie
- Cookie是在浏览器访问web服务器的某个资源时,由web服务器在http响应消息头中附带传送给浏览器的一小段数据;
- 一旦Web浏览器保存了某个Cookie,那么它在以后每次访问该web服务器时,都应在HTTP请求头中将这个Cookie回传给Web服务器
-
一个Cookie主要由表示该信息的名称和值组成
4.2.1 Cookie的创建
package com.qf.cookies;
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;
@WebServlet(value = "/cs")
public class CookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、服务器创建Cookie对象
Cookie cookie = new Cookie("username","gavin" );
//2、将Cookie响应给客户端
resp.addCookie(cookie);
}
}
4.2.2 设置Cookie的访问路径
4.2.3 设置Cookie的生命周期
4.3 获取Cookie
- 这个实验,我们验证两个问题
- 第一个问题是:如何获取Cookie?
- 第二个问题是:如果在创建Cookie时,设置了访问路径,那么在路径之外访问会是什么样子?
package com.qf.cookies;
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;
@WebServlet(value = "/cs")
public class CookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 服务器创建Cookie对象
Cookie cookie = new Cookie("username","gavin" );
Cookie cookie2 = new Cookie("password", "123456");
//1.1 设置Cookie的访问路径
cookie.setPath("/Webproject_war_exploded/get");
cookie2.setPath("/Webproject_war_exploded");
//1.2 设置Cookie的有效期
cookie.setMaxAge(60*60);
cookie2.setMaxAge(60*60);
//2. 将Cookie响应给客户端
resp.addCookie(cookie);
resp.addCookie(cookie2);
}
}
- 首先看创建Cookie服务的代码,在cookie对象中,设置了只有/get资源能够访问
- 之后分别看获取Cookie的代码
// GetServle.java
package com.qf.cookies;
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;
@WebServlet(value = "/get")
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 通过request获取所有的cookie
Cookie[] cookies = req.getCookies();
// 2.通过循环遍历Cookie
if (cookies != null) {
for (Cookie cookie : cookies) {
System.out.println(cookie.getName() + ':' + cookie.getValue());
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
// GetServle2.java
package com.qf.cookies;
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;
@WebServlet(value = "/get2")
public class GetServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 通过request获取所有的cookie
Cookie[] cookies = req.getCookies();
// 2.通过循环遍历Cookie
if (cookies != null) {
for (Cookie cookie : cookies) {
System.out.println(cookie.getName() + ':' + cookie.getValue());
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 我们看一下执行结果:由于cookie对象实例的访问路径不包含get2资源,因此在get2资源访问时,无法打印出其信息
4.4 修改Cookie
-
只需要保证Cookie的名和路径一致即可修改
4.5 Cookie编码与解码
- Cookie默认不支持中文,只能包含ASCII字符,所以Cookie需要对Unicode字符进行编码,否则会出现乱码
- 编码可以使用java.net.URLEncoder类的encode(String str,String encoding)方法;
- 解码可以使用java.net.URLDncoder类的dncode(String str,String encoding)方法;
5 Cookie优缺点
- 优点:
- 可配置到期规则
- 简单性:Cookie是一种基于文本的轻量结构,包含简单的键值对
- 数据持久性:Cookie默认在到期之前是可以一直保存在客户端浏览器上的
- 缺点:
- 大小受到限制:大多数浏览器对Cookie的大小是有4K、8字节的限制
- 用户配置为禁用:用户Ban了
- 潜在的安全风险:Cookie可能会被篡改
网友评论