会话技术之Cookie
中文饼干. 其实是一份小数据, 是服务器给客户端,并且存储在客户端上的一份小数据
cookie_2">什么是cookie
浏览器端的会话技术,它通过在浏览器中记录一些服务器传递过来的数据,解决会话从什么时候开始,
到什么时候结束。
应用场景
自动登录(记住用户名和密码)、浏览记录、购物车。
为什么要有这个Cookie
http的请求是无状态。 客户端与服务器在通讯的时候,是无状态的,其实就是客户端在第二次来访的时候,服务器根本就不知道这个客户端以前有没有来访问过。 为了更好的用户体验,更好的交互 [自动登录],其实从公司层面讲,就是为了更好的收集用户习惯[大数据]
Cookie怎么用
添加Cookie给客户端
- 在响应的时候,添加cookie(也就是说添加Cookie需要用响应对象
response
)
java"> Cookie cookie = new Cookie("user-key", "caixunkun_lsdah34852");
//给响应,添加一个cookie
response.addCookie(cookie);
- 客户端收到的信息里面,响应头中多了一个字段 Set-Cookie ,如果没有刷新一下。
cookieAPI_23">cookie常用方法(API)
java">Cookie(String name, String value) 创建cookie对象
String getName() 获取cookie的名称
String getValue() 获取cookie的值
void setPath(String uri) 设置cookie的路径——浏览器根据这个路径判断那些cookie 要发送给服务器
void setMaxAge(int expiry) 设置cookie的最大生存时间(单位:秒),超过了该时间后Cookie会 自动销毁
注意:
cookie主要是通过名称和路径来确定他的唯一性的 .
例如:以下表示的是两个cookie,虽然名字一样 , 但是路径不同 , 所以两个cookie可以同时
存在。
/day04/a/b/cookie1
/day04/a/cookie1
如果路径和名称一样,后添加的cookie将覆盖前者
获取客户端带过来的Cookie
获取Cookie需要用到请求对象request
java">//获取客户端带过来的cookie
Cookie[] cookies = request.getCookies();
if(cookies != null){
for (Cookie c : cookies) {
String cookieName = c.getName();
String cookieValue = c.getValue();
System.out.println(cookieName + " = "+ cookieValue);
}
}
清除Cookie
Cookie没有提供delete方法,我们要删除需要设置maxAge 为0 。
java"> Cookie cookie = new Cookie("history","");
cookie.setMaxAge(0); //设置立即删除
cookie.setPath("/CookieDemo02");
response.addCookie(cookie);
其他常用方法
java">//关闭浏览器后,cookie就没有了。 ---> 针对没有设置cookie的有效期。
// expiry: 有效 以秒计算。
//正值 : 表示 在这个数字过后,cookie将会失效。
//负值: 关闭浏览器,那么cookie就失效, 默认值是 -1
cookie.setMaxAge(60 * 60 * 24 * 7);
//赋值新的值
//cookie.setValue(newValue);
//用于指定只有请求了指定的域名,才会带上该cookie
cookie.setDomain(".itheima.com");
//只有访问该域名下的cookieDemo的这个路径地址才会带cookie
cookie.setPath("/CookieDemo");
演示代码
前台JSP代码演示
index.jap页面展示
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<a href="cookieServlet?action=add">添加Cookie后台</a>
<br />
<a href="cookieServlet?action=read">获取Cookie后台</a>
<br />
<a href="cookieServlet?action=update">修改Cookie后台</a>
<br />
<a href="cookieServlet?action=del">清除Cookie后台</a>
</body>
</html>
second.jsp代码展示
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<h1>Cookie添加成功</h1>
<h2>添加到Cookie中的数据:user-key->${cookie["user-key"] }</h2>
</body>
</html>
servlet_123">后台servlet代码演示
java">import java.io.IOException;
import java.io.PrintWriter;
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;
@WebServlet("/cookieServlet")
public class CookieServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String action = req.getParameter("action");
switch(action) {
case "add":
addCookie(req, resp);
break;
case "read":
getCookie(req, resp);
break;
case "update":
updateCookie(req, resp);
break;
case "del":
delCookie(req, resp);
break;
default:
break;
}
}
/**
* 删除cookie
* @param req
* @param resp
* @throws IOException
*/
private void delCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html;charset=UTF-8");
// 根据key获取对应的cookie对象
Cookie cookie = getCooKie("user-key", req);
if(cookie == null) {
resp.getWriter().println("user-key这个cookie不存在!");
return;
}
// 从request中获取的cookie只有key和value,是不带domain、path这些属性的,domain属性如果不一致时无法清除cookie的
//如果不信把下面的cookie.setDomain("www.baidu.com")放开 cookie.setDomain("localhost");这个给注释上你就清除不来cookie
// cookie.setDomain("www.baidu.com");
cookie.setDomain("localhost");
cookie.setMaxAge(0); // 将该cookie的有效期设置成0(表示立马失效) (也就是说服务端只是改下有效期,清除cookie的操作还是客户端来做的)
resp.addCookie(cookie); // 重新将修改过有效期的cookie写入浏览器
resp.sendRedirect("cookieServlet?action=read"); // 跳转到获取cookie
}
/**
* 更新cookie
*
* @param req
* @param resp
* @throws IOException
*/
private void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html;charset=UTF-8");
// 根据key获取对应的cookie对象
Cookie cooKie = getCooKie("user-key", req);
if(cooKie == null) {
resp.getWriter().println("user-key这个cookie不存在!");
return;
}
//更新操作
cooKie.setValue("huangzilong");// 修改cookie的值
resp.addCookie(cooKie);// 重新将修改过有效期的cookie写入浏览器
resp.sendRedirect("cookieServlet?action=read"); // 跳转到获取cookie
}
/**
* 获取cookie
* @param req
* @param resp
* @throws IOException
*/
private void getCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
//获取单个Cookie
out.println("-----------------获取cookie中指定数据---------------<br />");
String userKey = getCooKieValue("user-key",req);
out.println("Cookie中userKey的值: " + userKey + "<br />");
// 获取Cookie中所有的数据
out.println("-----------------获取cookie中所有数据---------------<br />");
for(Cookie cookie : req.getCookies()) {
out.println(cookie.getName() + ":" + cookie.getValue() + "<br />");
}
out.println("<hr>");
out.println("<a href='index.jsp'>回到首页</a>");
}
/**
* 添加 cookie
* @param req
* @param resp
* @throws IOException
*/
private void addCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//创建Cookie
Cookie cookie = new Cookie("user-key", "caixunkun_lsdah34852");
// 试想一下,如果天猫能随便读取京东的cookie是什么后果?
// cookie支持按照域名隔离, 方法就是给cookie设置指定的domain,这样只有对应domain的请求才会带上自己domain下的cookie
// cookie.setDomain("www.baidu.com"); // setDomain如果设置默认就是当前请求的domain
// cookie.setPath("/aa"); // 进一步隔离, 只有访问该域名下的指定地址请求时才会带上该cookie
cookie.setMaxAge(30); // 设置cookie有效期,单位:秒 (默认和session的有效期一样)
// 通过响应对象将Cookie写入客户端
resp.addCookie(cookie);
// 重定向到second.jsp
resp.sendRedirect("second.jsp");
}
/**
* 按照key获取cookie中对应的值
*
* @param key
* @param req
* @return 如果没找到,返回null
*/
private String getCooKieValue(String key, HttpServletRequest req) {
Cookie[] cookies = req.getCookies();
if (cookies == null) {
return null;
}
for (Cookie cookie : cookies) {
if(cookie.getName().equals(key)) {
return cookie.getValue();
}
}
return null;
}
/**
* 按照key获取cookie对象
* @param key
* @param req
* @return 如果没找到,返回null
*/
private Cookie getCooKie(String key, HttpServletRequest req) {
Cookie[] cookies = req.getCookies();
if(cookies==null) {
return null;
}
for (Cookie cookie : cookies) {
if(cookie.getName().equals(key)) {
return cookie;
}
}
return null;
}
}
在浏览器地址栏中输入项目路径,打开f12
点第一个添加cookie,刷新
读取cookie中的值如下
修改cookie中的值如下
删除cookie中的值如下
可以做一个练习比如 记住密码登录
cookie_300">cookie总结
-
服务器给客户端发送过来的一小份数据,并且存放在客户端上。
-
获取cookie
request.getCookie();
-
添加cookie
response.addCookie();
-
Cookie有效时间
-
会话Cookie
默认情况下,关闭了浏览器,那么cookie就会消失。
这是默认的行为,但是大部分现代的浏览器都不会这么做,比如chrome浏览器,默认打开时会恢复上次关闭时的状态,所有关闭浏览器cookie并不会失效。 我们可以设置浏览器打开时不恢复上次状态,改为打开新的标签页即可。
-
持久Cookie
通过设置MaxAge指定存活时间,在存活时间内,都有效,并且会保存在客户端上。
cookie.setMaxAge(0); //设置立即删除 cookie.setMaxAge(100); //100 秒
-
-
Cookie的安全问题。
由于Cookie会保存在客户端上,所以有安全隐患问题。 还有一个问题, Cookie的大小与个数有限制。 为了解决这个问题 —> Session .
-
Cookie不能直接存储中文,需要做转码