插播:
学习这块知识的时候在网上采集资料,发现网上大都是理论讲解,让不理解这块的人实在摸不清头脑,当你需要互联网辅助学习时却发现搜索到的都是相同的帖子,没有营养.我想那些写完帖子乃至博客的人又能理解cookie多少,让你使用代码演示,你又能演示的出来效果吗?简直凉了自己的心!
Cookie是服务器响应给客户端的少量数据
- 用于记录上次浏览网页位置
- 用于存储当前登录的用户信息
- 用于存储token信息(以后再详说)
- 存储指定网页的用户名和密码,实现自动登录
一.cookie设置的相关方法
方法 | 描述 |
---|---|
setMaxAge(int expiry) | 设置cookie的失效时间 |
setPath(String uri) | 设置cookie的携带路径 ①如果设置为“/ABC/”,则只有uri为“/ABC”的程序可以访问该Cookie ②如果设置为“/”,则本域名下的uri都可以访问该Cookie。注意最后一个字符必须为"/" |
setDomain(String domain) | 设置cookie的跨域共享域名匹配规则 ①如果设置为“.google.com” ②以“google.com”结尾的域名都可以访问该Cookie。注意第一个字符必须为“.” |
setComment(String purpose) | 对该cookie进行描述的信息(说明作用),浏览器显示cookie信息时能看到 |
setSecure(boolean flag) | 是否使用安全传输协议 当flag为true时,只有https的请求时才会携带cookie |
setValue(String newValue) | 给当前cookie赋值 |
二.cookie获取的相关方法
方法 | 描述 |
---|---|
int getMaxAge() | 获取cookie的失效时间 |
String getPath() | 获取cookie的携带路径 |
String getDomain() | 获取cookie的跨域共享域名 |
String getComment() | 获取cookie的描述信息 |
boolean getSecure() | 获取cookie是否使用传输协议标识 |
String getValue() | 获取cookie中的属性值 |
三.setPath(String uri)
这个地方是最让我纠结的地方,但是还是克服了,以下分为几种情况讨论setPath的应用场景及其效果
1.servlet程序虚拟路径/sc;cookie不设置携带路径
①测试前准备:
- 虚拟访问路径为"/sc"的cookie生成程序:SetCookies.java
- 虚拟访问路径为"/abc/fgc"的获取cookie程序:FirGetCookies.java
- 虚拟访问路径为"/sgc"的获取cookie程序:SecGetCookies.java
②代码展示:
***SetCookies.java
package controller.cookie;
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;
/**
* @Author weihuanwen
* @Date 2019/7/28 11:50
* @Version 1.0
*/
@WebServlet(urlPatterns = "/sc")
public class SetCookies extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//工程根目录
String contextPath = req.getContextPath();
//创建cookie
Cookie cookie = new Cookie("name","Howie");
//设置生命周期
cookie.setMaxAge(60*60);
resp.addCookie(cookie);
cookie.getValue();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
***FirGetCookies.java
package controller.cookie;
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;
/**
* @Author weihuanwen
* @Date 2019/7/28 11:50
* @Version 1.0
*/
@WebServlet(urlPatterns = "/abc/fgc")
public class FirGetCookies extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
System.out.println("FirGetCookies ::: ["+cookie.getName()+" : "+cookie.getValue()+"]");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
***SecGetCookies.java
package controller.cookie;
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;
/**
* @Author weihuanwen
* @Date 2019/7/28 11:50
* @Version 1.0
*/
@WebServlet(urlPatterns = "/sgc")
public class SecGetCookies extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
System.out.println("SecGetCookies ::: ["+cookie.getName()+" : "+cookie.getValue()+"]");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
③测试:
访问:http://localhost:8080/cr/sc
设置cookie如下:
访问:http://localhost:8080/cr/sgc
控制台输出如下:
SecGetCookies ::: [name : Howie]
SecGetCookies ::: [login_member_telephone : 13888888888]
访问:http://localhost:8080/cr/abc/fgc
控制台输出如下:
FirGetCookies ::: [name : Howie]
SecGetCookies ::: [login_member_telephone : 13888888888]
④总结:
虚拟路径为"/sc"的程序中生成的cookie默认携带路径为项目根路径,因此无论是访问"/abc/fgc"还是访问"/sgc",都会携带cookie
2.servlet程序虚拟路径/abc/sc;cookie不设置携带路径
①测试前准备:
- 虚拟访问路径为"/abc/sc"的cookie生成程序:SetCookies.java
- 虚拟访问路径为"/abc/fgc"的获取cookie程序:FirGetCookies.java
- 虚拟访问路径为"/sgc"的获取cookie程序:SecGetCookies.java
②代码展示:
***SetCookies.java
单纯将虚拟访问路径修改为"/abc/sc",其它无改变
@WebServlet(urlPatterns = "/abc/sc")
***FirGetCookies.java
代码无改变
***SecGetCookies.java
代码无改变
③测试:
访问:http://localhost:8080/cr/abc/sc
设置cookie如下:
访问:http://localhost:8080/cr/sgc
控制台输出如下:
SecGetCookies ::: [login_member_telephone : 13888888888]
访问:http://localhost:8080/cr/abc/fgc
控制台输出如下:
FirGetCookies ::: [name : Howie]
FirGetCookies ::: [login_member_telephone : 13888888888]
④总结:
虚拟路径为"/abc/sc"的程序中生成的cookie默认携带路径为"/abc",因此
访问"/abc/fgc"会携带cookie
访问"/sgc"不会携带cookie
3.servlet程序虚拟路径/abc/sc;cookie设置携带路径为"/"(这里通过rquest的getContextPath()获取)
①测试前准备:
- 虚拟访问路径为"/abc/sc"的cookie生成程序:SetCookies.java
- 虚拟访问路径为"/abc/fgc"的获取cookie程序:FirGetCookies.java
- 虚拟访问路径为"/sgc"的获取cookie程序:SecGetCookies.java
②代码展示:
***SetCookies.java
package controller.cookie;
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;
/**
* @Author weihuanwen
* @Date 2019/7/28 11:50
* @Version 1.0
*/
@WebServlet(urlPatterns = "/abc/sc")
public class SetCookies extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//工程根目录
String contextPath = req.getContextPath();
//创建cookie
Cookie cookie = new Cookie("name","Howie");
//设置生命周期
cookie.setMaxAge(60*60);
//设置携带路径(数据共享范围)
cookie.setPath(req.getContextPath());
resp.addCookie(cookie);
cookie.getValue();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
***FirGetCookies.java
代码无改变
***SecGetCookies.java
代码无改变
③测试:
访问:http://localhost:8080/cr/abc/sc
设置cookie如下:
访问:http://localhost:8080/cr/sgc
控制台输出如下:
SecGetCookies ::: [name : Howie]
SecGetCookies ::: [login_member_telephone : 13888888888]
访问:http://localhost:8080/cr/abc/fgc
控制台输出如下:
FirGetCookies ::: [name : Howie]
FirGetCookies ::: [login_member_telephone : 13888888888]
④总结:
虚拟路径为"/abc/sc"的程序中生成的cookie设置携带路径为项目根路径,无论访问"/abc/fgc"还是"/sgc"都会携带cookie
4.servlet程序虚拟路径/sc;cookie设置携带路径为"/abc"(这里通过rquest的getContextPath()+"/abc"表示)
①测试前准备:
- 虚拟访问路径为"/sc"的cookie生成程序:SetCookies.java
- 虚拟访问路径为"/abc/fgc"的获取cookie程序:FirGetCookies.java
- 虚拟访问路径为"/sgc"的获取cookie程序:SecGetCookies.java
②代码展示:
***SetCookies.java
package controller.cookie;
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;
/**
* @Author weihuanwen
* @Date 2019/7/28 11:50
* @Version 1.0
*/
@WebServlet(urlPatterns = "/sc")
public class SetCookies extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//工程根目录
String contextPath = req.getContextPath();
//创建cookie
Cookie cookie = new Cookie("name","Howie");
//设置生命周期
cookie.setMaxAge(60*60);
//设置携带路径(数据共享范围)
cookie.setPath(req.getContextPath()+"/abc");
resp.addCookie(cookie);
cookie.getValue();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
***FirGetCookies.java
代码无改变
***SecGetCookies.java
代码无改变
③测试:
访问:http://localhost:8080/cr/sc
设置cookie如下:
访问:http://localhost:8080/cr/sgc
控制台输出如下:
SecGetCookies ::: [login_member_telephone : 13888888888]
访问:http://localhost:8080/cr/abc/fgc
控制台输出如下:
FirGetCookies ::: [name : Howie]
FirGetCookies ::: [login_member_telephone : 13888888888]
④总结:
虚拟路径为"/sc"的程序中生成的cookie设置携带路径为"/abc",因此
访问"/abc/fgc"会携带cookie
访问"/sgc"不会携带cookie
四.服务器端如何完成cookie的清除?
当然这里并不是指你在浏览器里Ctrl+Alt+Del清除cookie那样
我们要做到的是如何在服务器端实现cookie的清除
昨天一直在思考这个问题,没有头绪(代表着以后也有可能会忘记),所以我认为有必要将这个思路记录下来
思路:
- 服务器端获取cookie
- 设置cookie的失效时间为0
- 将cookie响应回前端
package controller.cookie;
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;
/**
* @Author weihuanwen
* @Date 2019/7/28 11:50
* @Version 1.0
*/
@WebServlet(urlPatterns = "cc")
public class ClrCookies extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
if("name".equals(cookie.getName())){
cookie.setMaxAge(0);
resp.addCookie(cookie);
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
五.cookie中包含中文会显示乱码的解决方案
URLDecoder 解码
静态方法 decoder(字符串,编码表)
URLEncoder 编码
静态方法 encoder(字符串,编码表)
①编码cookie
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//将value转为utf-8
String value = URLEncoder.encode("会不会乱码","utf-8");
Cookie cookie = new Cookie("content",value);
response.addCookie(cookie);
//客户端:Set-Cookie:content=%BA%C3%BA%C3%D1%A7%CF%B0%CC%EC%CC%EC%CF%F2%C9%CF
}
②解码cookie
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
String name = cookie.getName();
if ("content".equals(name)){
//解码
String value = URLDecoder.decode(cookie.getValue(), "utf-8");
System.out.println(name+"="+value);//content=会不会乱码
}
}
}