Cookie概念与原理
- Cookie是浏览器访问Web服务器的某个资源时,由Web服务器在HTTP响应消息头中附带传送给浏览器的一小段数据
- 一旦Web浏览器保存了某个Cookie,那么它在以后每次访问该Web服务器时,都应在HTTP请求头中将这个Cookie回传给Web服务器
- 一个Cookie主要有标识该信息的名称(name)和值(value)组成
简单应用
package cn.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("/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 {
Cookie cookie = new Cookie("name","zhangsan"); // 创建Cookie对象
cookie.setPath("/ServletDemo_war_exploded/get"); // 设置Cookie的访问路径,只有该项目下的get及get下的资源可以访问这个Cookie
cookie.setMaxAge(60*60); //Cookie的有效期 取值有三种:>0有效期 单位秒; =0浏览器关闭; <0内存存储,默认-1 例:设置 60* 60 即有效期为 一个小时
resp.addCookie(cookie); // 将cookie响应给客户端
// 有效路径: 当前访问资源的的上一级目录,不带主机名
}
}
获取Cookie
package cn.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("/get")
public class getCookie 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 {
// 获取所有Cookie
Cookie[] cookies = req.getCookies();
if (cookies != null){
// 遍历Cookie
for (Cookie cok : cookies) {
System.out.println(cok.getName() + ":" + cok.getValue());
}
}
}
}
修改Cookie
- 需要保证Cookie的名和路径一致
- 如果改变cookie的name和有效路径会新建一个cookie,而改变cookie值,有效期会覆盖原有cookie
package cn.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("/cs2")
public class cookieServlet2 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 {
// 修改cookie
Cookie cookie = new Cookie("name","lisi"); // 创建一个Cookie,name值与cookieServlet的cookie一致
cookie.setPath("/ServletDemo_war_exploded/get"); //设置cookie的访问路径与cookieServlet的cookie一致
cookie.setMaxAge(60*60*24); // 修改cookie,有效期会覆盖
resp.addCookie(cookie); // 提交cookie
}
}
Cookie编码与解码
Cookie默认不支持中文,只能包含ASCII字符,所以Cookie需要对Unicode字符进行编码,否则会出现乱码.
- 编码可以使用Java.net.URLEncoder类的encode(String str,String encoding)方法
- 解码可以使用Java.net.URLDecode类的decode(String str,String encoding)方法
编码
package cn.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;
import java.net.URLEncoder;
@WebServlet("/cs3")
public class cookieServlet3 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 {
// 创建Cookie
// 对数据进行编码
Cookie cookie = new Cookie(URLEncoder.encode("姓名","utf-8"),URLEncoder.encode("张三","utf-8"));
// 设置访问路径
cookie.setPath("/ServletDemo_war_exploded/get");
// 设置有效期
cookie.setMaxAge(60*60);
// 提交cookie
resp.addCookie(cookie);
}
}
解码
package cn.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;
import java.net.URLDecoder;
@WebServlet("/get")
public class getCookie 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 {
// 获取所有Cookie
Cookie[] cookies = req.getCookies();
if (cookies != null){
// 遍历Cookie
for (Cookie cok : cookies) {
// 对cookie进行解码输出
System.out.println(URLDecoder.decode(cok.getName(),"utf-8") + ":" + URLDecoder.decode(cok.getValue(),"utf-8"));
}
}
}
}
总结
优点
- 可配置到期时间
- 简单性: Cookie是一种基于文本的轻量结构,包含简单的键值对
- 数据可持久性: Cookie默认在过期之前是可以一直存在客户端浏览器上的
缺点
- 大小收到限制: 大多数浏览器对Cookie的大小有4K,8K字节的限制
- 用户配置为限制: 有些用户禁用了浏览器或客户端设备接受Cookie的能力,因此限制了这一功能
- 潜在的安全风险: Cookie可能会被篡改,会对安全性造成潜在风险或者导致依赖于Cookie的应用程序失败