目录
Web 开发会话技术之 -Cookie
会话
基本介绍
1. 什么是会话?
2. 会话过程中要解决的一些问题?
CreateCookie
访问 CreateCookie.java, 使用浏览器抓包分析 , 创建 Cookie 的底层机制
ReadCookie.java
访问 ReadCookie.java, 使用浏览器抓包分析 读取 Cookie 的底层机制.
不同会话,jsessionid 不同
代码
读取指定 Cookie
工具类
-修改 Cookie
介绍
代码示例
3. 完成测试 , 注意抓包看数据
有效路径规则
3. 规则如下:
代码示例
3. 完成测试 , 注意抓包看创建 Cookie 时,返回的数据
4. 完成测试 , 注意抓包看读取 Cookie 时,返回的数据
代码示例
html页面
java
Cookie 注意事项和细节
代码解决
设置
解码
Web 开发会话技术之 -Cookie
会话
基本介绍
1. 什么是会话?
会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个 web 资源,然
后关闭浏览器,整个过程称之为一个会话。
2. 会话过程中要解决的一些问题?
1) 每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,服
务器要想办法为每个用户保存这些数据
2) 例如:多个用户点击超链接通过一个 servlet 各自购买了一个商品,服务器应该想办法
把每一个用户购买的商品保存在各自的地方,以便于这些用户点结帐 servlet 时,结帐
servlet 可以得到用户各自购买的商品为用户结帐。
cookie 技术
Cookie是客户端技术,服务器把每个用户的数据以 cookie 的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的 web 资源时,就会带着各自的数据去。这样,web 资源处理的就是用户各自的数据了。【简单示意图】
cookie 介绍
二说 cookie
1. Cookie 是服务器在客户端保存用户的信息,比如登录名,浏览历史等, 就可以以 cookie方式保存.
2. Cookie 信息就像是小甜饼(cookie 中文)一样,数据量并不大,服务器端在需要的时候可以从客户端/浏览器读取(http 协议),可以通过图来理解
再次说明: cookie 数据是保存在浏览器的.
cookie 可以用来做啥
1. 保存上次登录时间等信息
2. 保存用户名,密码, 在一定时间不用重新登录
3. 网站的个性化,比如定制网站的服务,内容
cookie 基本使用
cookie 常用方法
1. Cookie 有点象一张表(K-V),分两列,一个是名字,一个是值,数据类型都是 String , 如图
2. 如何创建一个 Cookie(在服务端创建的)
Cookie c=new Cookie(String name,String val);
c.setMaxAge();//保存时间
3. 如何将一个 Cookie 添加到客户端
response.addCookie(c);
4. 如何读取 cookie(在服务器端读取到 cookie 信息)
request.getCookies();
cookie 底层实现机制-创建和读取 Cookie
1. 需求: 演示 Cookie 底层实现机制, 创建和读取Cookie
CreateCookie
/**
* 演示如何创建cookie,并保存到浏览器
*/
public class CreateCookie extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("CreateCookie 被调用...");
//1. 创建一个Cookie对象
//1) username 该cookie的名字 是唯一, 可以理解成是key
//2) xxx : 该cookie的值
//3) 可以创建多个cookie,老师就创建了一个
//4) 这是cookie在服务器端, 还没有到浏览器
Cookie cookie = new Cookie("username", "tom");
Cookie cookie2 = new Cookie("email", "tom@qq.com");
response.setContentType("text/html;charset=utf-8");
//2. 将cookie发送给浏览器, 让浏览器将该cookie保存
response.addCookie(cookie);
response.addCookie(cookie2);
PrintWriter writer = response.getWriter();
writer.println("<h1>创建cookie成功~</h1>");
writer.flush();
writer.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
访问 CreateCookie.java, 使用浏览器抓包分析 , 创建 Cookie 的底层机制
ReadCookie.java
/**
* 读取从浏览器发送来的cookie信息[底层仍然是http协议]
*/
public class ReadCookies extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ReadCookies 被调用..");
//1. 通过request对象读取cookie信息
Cookie[] cookies = request.getCookies();
//2. 遍历cookie
if (cookies != null && cookies.length != 0) {
for (Cookie cookie : cookies) {
System.out.println("cookie name= " + cookie.getName()
+ " value= " + cookie.getValue());
}
}
//3. 给浏览器返回信息
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("<h1>读取cookie信息成功~</h1>");
writer.flush();
writer.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
访问 ReadCookie.java, 使用浏览器抓包分析 读取 Cookie 的底层机制.
不同会话,jsessionid 不同
代码
读取指定 Cookie
public class ReadCookieByNameServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//System.out.println("ReadCookieByNameServlet 被调用..");
//得到指定的cookie的value
//1. 先得到浏览器携带的所有cookie
Cookie[] cookies = request.getCookies();
//2. 使用工具类来获取指定的cookie
Cookie emailCookie = CookieUtils.readCookieByName("username", cookies);
if(null != emailCookie) {
System.out.println("得到cookie name=" + emailCookie.getName()
+ " value= " + emailCookie.getValue());
} else {
System.out.println("sorry, 没有这个cookie");
}
//3. 给浏览器返回信息
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("<h1>完成读取cookie的任务..</h1>");
writer.flush();
writer.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
工具类
public class CookieUtils {
//编写一个方法,返回指定名字的cookie值
public static Cookie readCookieByName(String name, Cookie[] cookies) {
//判断传入的参数是否正确
if (name == null || "".equals(name) || cookies == null || cookies.length == 0) {
return null;
}
//遍历cookies
for (Cookie cookie : cookies) {
if(name.equals(cookie.getName())) {
return cookie;
}
}
return null;
}
}
-修改 Cookie
public class UpdateCookie extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("UpdateCookie 被调用...");
//需求
/**
* 1. 需求 演示如何修改Cookie
* 1) 给定一个cookie的name, 找到该cookie, 如果找到, 则修改该cookie的值为 -hi
* 2) 如果找不到指定的cookie , 则提示, 没有该cookie
*/
//1. 根据name 去查找 cookie
String cookieName = "emailx";
Cookie[] cookies = request.getCookies();
//如果我们直接创建了一个同名的cookie也相当于修改
Cookie userNameCookie = new Cookie("username", "hahaha");
Cookie cookie = CookieUtils.readCookieByName(cookieName, cookies);
if (null == cookie) {//在该浏览器没有email cookie
System.out.println("当前访问 服务端的 浏览器没有 该cookie");
} else {
cookie.setValue("hi");
}
System.out.println("=====修改后的cookies信息=======");
//2. 编写cookie
for (Cookie cookie1 : cookies) {
System.out.println("cookie name= " + cookie1.getName()
+ " value= " + cookie1.getValue());
}
//3. 给浏览器返回信息
response.setContentType("text/html;charset=utf-8");
//4. 如果希望我们的浏览器本地的cookie也修改,则需要使用response.addCookie(cookie);
if(cookie != null) {
response.addCookie(cookie);
}
//把 新创建的userNameCookie 重新保存到浏览器
//如果 保存的userNameCookie 和已经有的cookie同名,就等价于替换.
if(userNameCookie != null) {
response.addCookie(userNameCookie);
}
PrintWriter writer = response.getWriter();
writer.println("<h1>完成修改cookie的任务..</h1>");
writer.flush();
writer.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
cookie 生命周期
介绍
1. Cookie 的生命周期指的是如何管理 Cookie 什么时候被销毁(删除)
2. setMaxAge()
● 正数,表示在指定的秒数后过期
● 负数,表示浏览器关闭,Cookie 就会被删除(默认值是-1)
● 0,表示马上删除 Cookie
代码示例
public class CookieLive extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("CookieLive 被调用...");
//演示创建一个cookie , 生命周期为 60s
Cookie cookie = new Cookie("job", "java");
//解读:
// 1. 从创建该cookie开始计时, 60秒后无效
// 2. 浏览器来根据创建的时间,计时到60s秒,就认为该cookie无效
// 3. 如果该cookie无效,那么浏览器在发出http请求时,就不在携带该cookie
cookie.setMaxAge(60);
//将cookie保存到浏览器
response.addCookie(cookie);
//演示如何删除一个cookie, 比如删除username
//1 先得到username cookie
Cookie[] cookies = request.getCookies();
Cookie usernameCookie =
CookieUtils.readCookieByName("username", cookies);
if(usernameCookie != null) {
//2. 将其生命周期设置为0
usernameCookie.setMaxAge(0);
//3. 重新保存该cookie, 因为你将其生命周期设置0, 就等价于让浏览器删除该cookie
//4. 说明:该cookie会被浏览器直接删除
// 返回一个Set-Cookie: xxxxx => 一会抓包.
// Set-Cookie: username=tom; Expires=Thu, 01-Jan-1970 00:00:10 GMT
response.addCookie(usernameCookie);//返回一个Set-Cookie: xxxxx => 一会抓包.
}else{
System.out.println("没有找到该cookie, 无法删除...");
}
/***********************
* 默认的会话级别的 Cookie [即浏览器关闭就销毁了]
* 前面我们讲课时,都是默认会话级别的生命周期
***********************/
Cookie cookie3 = new Cookie("dkey", "dkey_value");
/**
* 解读 setMaxAge源码
* public void setMaxAge(int expiry) {
* this.maxAge = expiry;
* }
* private int maxAge = -1; 默认就是-1
*/
//cookie.setMaxAge(-1);//设置存活时间
response.addCookie(cookie3);
// 给浏览器返回信息
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("<h1>设置cookie生命周期</h1>");
writer.flush();
writer.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
3. 完成测试 , 注意抓包看数据
cookie 有效路径
有效路径规则
1. Cookie 有效路径 Path 的设置
2. Cookie 的 path 属性可以有效的过滤哪些 Cookie 可以发送给服务器。哪些不发。path属性是通过请求的地址来进行有效的过滤
3. 规则如下:
cookie1.setPath = /工程路径
cookie2.setPath = /工程路径/aaa
请求地址: http://ip:端口/工程路径/资源
cookie1 会发给服务器
cookie2 不会发给服务器
请求地址: http://ip:端口/工程路径/aaa/资源
cookie1 会发给服务器
cookie2 会发给服务器
代码示例
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CookiePathServlet 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 {
Cookie cookie = new Cookie("keyPath1", "keyPath1Value");
// request.getContextPath() + "/aaa" 得到 /工程路径/aaa
cookie.setPath(request.getContextPath() + "/aaa");
Cookie cookie2 = new Cookie("keyPath2", "keyPath2Value");
cookie2.setPath(request.getContextPath());
response.addCookie(cookie);
response.addCookie(cookie2);
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("<h1>创建 Cookie keyPath1 路径 /工程路径/aaa </h1>");
response.getWriter().write("<h1>创建 Cookie keyPath2 路径 /工程路径 </h1>");
}
}
3. 完成测试 , 注意抓包看创建 Cookie 时,返回的数据
4. 完成测试 , 注意抓包看读取 Cookie 时,返回的数据
代码示例
需求: 完成自动填写登录账户应用案例 , 如果用户登录成功,则下次登录自动填写登录 账户
html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<h1>用户登录界面</h1>
<form action="#" method="post">
u:<input type="text" name="username"><br/>
p:<input type="password" name="pwd"><br/>
<input type="submit" value="登录">
</form>
</body>
</html>
java
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//System.out.println("LoginServlet 被调用...~~~");
//1. 接收表单提交用户名和密码
String username = request.getParameter("username");
String pwd = request.getParameter("pwd");
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
//2. 判断是否合法
if ("xxxx".equals(username) && "123456".equals(pwd)) {
//将登录成功的用户名,以cookie的形式,保存到浏览器
Cookie loginuserCookie = new Cookie("loginuser", username);
//设置该cookie生命周期
loginuserCookie.setMaxAge(3600 * 24 * 3);
response.addCookie(loginuserCookie);
//合法
writer.println("<h1>登录OK</h1>");
} else {
//不合法
writer.println("<h1>登录失败</h1>");
}
writer.flush();
writer.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
Cookie 注意事项和细节
1. 一个 Cookie 只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
2. 一个 WEB 站点可以给一个浏览器发送多个 Cookie,一个浏览器也可以存储多个 WEB 站点提供的 Cookie。
3. cookie 的总数量没有限制,但是每个域名的 COOKIE 数量和每个 COOKIE 的大小是有限制的 (不同的浏览器限制不同, 知道即可) , Cookie 不适合存放数据量大的信息。
4. 注意,删除 cookie 时,path 必须一致,否则不会删除
5. Java servlet 中 cookie 中文乱码
说明 如果存放中文的 cookie, 默认报错, 可以通过 URL 编码和解码来解决, 不建议存 放中文的 cookie 信息
代码解决
设置
public class EncoderCookie extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//System.out.println("EncoderCookie 被调用");
//1. 创建cookie, 有中文
//1) 如果直接存放中文的cookie, 报错 Control character in cookie value or attribute.
//2) 解决方法,就是将中文 编程成 URL编码 英文: Encode=编码
//3) 编码后,再保存即可
String company = URLEncoder.encode("大家好", "utf-8");
Cookie cookie = new Cookie("company", company);
//2. 保存到浏览器
response.addCookie(cookie);
//3. 给浏览器返回信息
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("<h1>设置中文cookie成功</h1>");
writer.flush();
writer.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
解码
public class ReadCookie2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ReadCookie2 被调用..");
//读取到中文cookie
Cookie[] cookies = request.getCookies();
Cookie companyCookie = CookieUtils.readCookieByName("company",cookies);
String companyVal = companyCookie.getValue();
System.out.println("companyVal= " + companyVal);//URL
//解码
companyVal = URLDecoder.decode(companyVal, "utf-8");
System.out.println("解码后 companyVal= " + companyVal);//中文
//3. 给浏览器返回信息
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("<h1>读取中文cookie解码成功~</h1>");
writer.flush();
writer.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}