文章目录
Cookie详解
一、Cookie简介
1.1 什么是Cookie
Cookie是服务器通知客户端保存键值对的一种技术。当客户端有Cookie后,每次请求都发送给服务器。
注:
1、每个Cookie的大小不能超过4kb;
2、Cookie的值不应该包含空格、方括号[ ]、圆括号()、等号=、逗号,、双引号“”、斜杠\、问号?、@符号、冒号:和分号;。空值在所有浏览器上的行为也不一定相同。
3、如果一定要的话,就得用Base64编码
1.2 Java如何创建Cookie
直接代码送上:
首先是我们的BaseServlet.java文件
package com.hstc.edu;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
public class BaseServlet 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 {
//解决post请求中文乱码问题
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html; charset=UTF-8");
String action = req.getParameter("action");
try {
// 获取action业务鉴别字符串,获取相应的业务 方法反射对象
Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
// 调用目标业务方法
method.invoke(this, req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
然后是我们的CookieServlet.java文件:
package com.hstc.edu;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CookieServlet extends BaseServlet{
protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
System.out.println("我被调用了!!");
//1、创建Servlet对象
Cookie cookie = new Cookie("key1","value1");
//2、通知客户端保存Cookie
resp.addCookie(cookie);
resp.getWriter().write("Cookie创建成功");
}
}
然后我们在web.xml中注册我们的Servlet:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>CookieServlet</servlet-name>
<servlet-class>com.hstc.edu.CookieServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieServlet</servlet-name>
<url-pattern>/cookieServlet</url-pattern>
</servlet-mapping>
</web-app>
最后编写我们的脚本文件(HTML):
<!DOCTYPE html>
<html lang="ch">
<head>
<meta charset="UTF-8">
<title>Cookie学习实例</title>
<!--
这里的base指的是本网页基于的路径,跟下面可以直接用cookieServlet有直接关系
说直白点就是下面所有的路径都将会在最前面加上这个路径
-->
<base href="http://localhost:8080/Cookie/">
<style type="text/css">
iframe{
position: absolute;
left: 500px;
top: 0px;
}
ul li{
width: 300px;
list-style: none;
}
</style>
</head>
<body>
<div>
<ul>
<li>
<a href="cookieServlet?action=createCookie" target="target">Cookie的创建</a>
</li>
<li>
<a href="cookieServlet?action=" target="target">Cookie的获取</a>
</li>
<li>
<a href="cookieServlet?action=" target="target">修改Cookie值</a>
</li>
<li>Cookie的生命周期</li>
<li>
<ul>
<li>
<a href="cookieServlet?action=" target="target">Cookie的默认存活时长(会话)</a>
</li>
<li>
<a href="cookieServlet?action=" target="target">立刻删除Cookie</a>
</li>
<li>
<a href="cookieServlet?action=" target="target">让Cookie存活3600s(1小时)</a>
</li>
</ul>
</li>
<li>
<a href="cookieServlet?action=" target="target">Cookie的路径设置</a>
</li>
<li>
<a href="cookieServlet?action=" target="target">Cookie的用户免登陆练习</a>
</li>
</ul>
</div>
<iframe name="target" width="500" height="500"></iframe>
</body>
</html>
运行结果:
点击了Cookie的创建后:
Cookie创建的图文说明:
注意:Cookie可以同时创建多个。代码也很简单,请看:
package com.hstc.edu;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CookieServlet extends BaseServlet{
protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
//1、创建Servlet对象
Cookie cookie = new Cookie("key1","value1");
//2、通知客户端保存Cookie
resp.addCookie(cookie);
//同时创建并保存多个cookie
Cookie cookie2 = new Cookie("key2","value2");
Cookie cookie3 = new Cookie("key3","value3");
resp.addCookie(cookie2);
resp.addCookie(cookie3);
resp.getWriter().write("Cookie创建成功");
}
}
1.3 获取Cookie的name和value
在上面基础上,在CookieServlet.java类中编写函数:
protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException {
Cookie[] cookies = req.getCookies();
for(Cookie cookie : cookies){
resp.getWriter().write(cookie.getName()+": "+cookie.getValue()+"<br/>");
}
}
然后再html中做个引导:
然后运行服务器,点击Cookie的获取即可在iframe标签中显示当前所有的Cookie的信息。
1.4 寻找是否有特定Cookie
protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException {
Cookie myCookie = null;
Cookie[] cookies = req.getCookies();
for(Cookie cookie : cookies){
//使用你想获取的cookie的键去配对是否有你想要的cookie
if ("key2".equals(cookie.getName())){
//找到了,给myCookie赋值
myCookie = cookie;
//doSomething
System.out.println("小样,被我抓到了吧");
//找到了就break跳出for循环,不要乱费时间,这是好习惯
break;
}
}
//找不到怎么办
if(myCookie == null){
//doSomething
System.out.println("我找不到呀!!!");
}
}
鉴于这个方法比较常用,我们也可以把他封装成一个函数,放在utils包中,供我们日常使用:
package com.hstc.utils;
import javax.servlet.http.Cookie;
public class CookieUtils {
public static Cookie findCookie(String name,Cookie[] cookies){
//输出的参数不对劲,不给干活
if(name == null || cookies.length == 0 || cookies == null){
return null;
}
//找到了就返回cookie对象
for (Cookie cookie: cookies){
//查找有没有想要的Cookie
if (name.equals(cookie.getName())){
return cookie;
}
}
//找不到返回null值
return null;
}
}
使用的话只需要:
protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException {
Cookie myCookie = CookieUtils.findCookie("key2",req.getCookies());
if (myCookie != null){
//找到了,doSomething
System.out.println("我找到啦!!!");
}else {
//找不到,doSomething
System.out.println("骗谁呢你!!!");
}
}
1.5 Cookie值的修改
方案一(直接写新的盖上去)
步骤如下:
1、创建一个同名的Cookie对象
2、在构造器中,赋予Cookie值
3、调用response.addCookie(cookie)方法
protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException {
Cookie cookie = new Cookie("key1","newValue1");
resp.addCookie(cookie);
resp.getWriter().write("成功修改name为key1的Cookie值");
}
方案二(找到要改的,再用Cookie对象的方法改)
步骤:
1、查找要修改的Cookie对象
2、用cookie对象的setValue方法赋予新的值
3、用response的addCookie修改客户端的值
protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// Cookie cookie = new Cookie("key1","newValue1");
// resp.addCookie(cookie);
Cookie myCookie = CookieUtils.findCookie("key2",req.getCookies());
if (myCookie != null){
myCookie.setValue("NewValue2");
resp.addCookie(myCookie);
}
resp.getWriter().write("成功修改name为key2的Cookie值");
}
1.6 Cookie的生命控制
使用setMaxAge(int expiry)方法即可。
- 当expiry为正数n,表示存活n秒
- 当expiry为负数m,表示退出浏览器就消失(默认情况)
- 当expiry为0,表示马上删除Cookie
//默认情况,可以看Cookie类的代码,他是开源的
protected void defaultLife(HttpServletRequest req, HttpServletResponse resp){
Cookie cookie = new Cookie("life","defaultLife");
cookie.setMaxAge(-1);
resp.addCookie(cookie);
}
//等于0,让他马上消失
protected void deleteLife(HttpServletRequest req, HttpServletResponse resp){
Cookie cookie = new Cookie("delete","deleteLife");
cookie.setMaxAge(0);
resp.addCookie(cookie);
}
//等于正数,存活3600s,也就是一小时
protected void oneHourLife(HttpServletRequest request, HttpServletResponse response){
Cookie cookie = new Cookie("hour","hour");
cookie.setMaxAge(3600);
response.addCookie(cookie);
}
Cookie类的源码:
1.7 Cookie修改path属性
这个path有什么用呢?
作用:可以用来过滤哪些Cookie可以发送给服务器,哪些不发。
举个例子:
现在有CookieA和CookieB的path属性分别如下:
CookieA —— path = /Cookie
CookieB —— path=/Cookie/hello
现在,我们如果访问地址:
http:localhost:8080/Cookie/cookie.html
那么CookieA 会发送给服务器,CookieB则不会。
如果我们访问的地址是:
http:localhost:8080/Cookie/hello/cookie.html
那么,此时CookieA和CookieB都会发送给服务器。
那么,怎么设置path路径呢,很简单,只需要用Cookie对象的setPath()方法即可。演示代码来一波:
protected void updatePath(HttpServletRequest req, HttpServletResponse resp) throws IOException {
Cookie cookie = new Cookie("path","path1");
//request的getContextPath()方法用来获取工程路径
cookie.setPath(req.getContextPath() + "/hello");
resp.addCookie(cookie);
resp.getWriter().write("成功添加了path = 工程路径/path 的Cookie");
}
当点击Cookie的路径设置的时候,iframe标签成功显示成功添加了path = 工程路径/path 的Cookie,但是我们刷新Application的Cookie却发现,没有出来新的Cookie。
这是因为我们当前的路径是http://localhost:8080/Cookie/cookie.html,服务器不接收路径为http://localhost:8080/Cookie/hello的Cookie。
为了证明我没有动手脚,特地再截图一张Network下的图片,可以看到响应头的Set-Cookie里面是有设置path = path的。
此时,我们再访问路径http://localhost:8080/Cookie/hello/cookie.html,可以看到cookie值被放到了这里。
不仅如此,我们Path为/Cookie以及/的Cookie也全都可以看到。
1.8 Cookie实战——免用户名登录
实现过程:
代码走一波:
显示网页login.jsp文件的源码:
不会EL表达式的,点击此处,我已经准备了EL表达式的详细笔记。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录页面</title>
</head>
<body>
<form action="http://localhost:8080/Cookie/login" method="get">
用户名:<input type="text" name="username" value="${cookie.username.value}"><br>
密 码:<input type="password" name="password"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
然后是我们的Servlet程序,LoginServlet.java源码:
package com.hstc.edu;
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 LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
//登录成功保存Cookie
if(username.equals("Keeling") && password.equals("123456")){
Cookie cookie = new Cookie("username",username);
//Cookie保存一周
cookie.setMaxAge(3600 * 24 * 7);
resp.addCookie(cookie);
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
}
}
然后我们在web.xml进行注册:
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.hstc.edu.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>