什么是Cookie

Cookie是服务器通知客户端保存键值对的一种技术,是Servlet发送到web浏览器的信息(大小不能超过4kb),这些信息由浏览器保存,然后发送回服务器


Cookie的创建

新建动态web工程13_cookie_session,将两个HTML文件复制到web目录下,修改tomcat实例名、工程访问路径、配置热部署

17-Cookie和Session_html

cookie.html

17-Cookie和Session_html_02

复制book工程下的BaseServlet.java到src中,在其中增加解决乱码的代码

17-Cookie和Session_html_03

CookieServlet.java

package com.atguigu.servlet;

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,创建Cookie对象
Cookie cookie = new Cookie("key1", "value1");
// 2,通知客户端保存Cookie
resp.addCookie(cookie);

resp.getWriter().write("Cookie创建成功");
}
}

web.xml,重新部署

17-Cookie和Session_服务器_04

点击a标签“cookie的创建”

17-Cookie和Session_服务器_05

17-Cookie和Session_html_06

17-Cookie和Session_html_07

可以一次性创建多个Cookie

17-Cookie和Session_服务器_08

17-Cookie和Session_html_09

服务器端获取Cookie

cookie.html

17-Cookie和Session_服务器_10

CookieServlet.java

17-Cookie和Session_服务器_11

17-Cookie和Session_服务器_12

获取指定cookie

17-Cookie和Session_java_13

获取指定cookie是很常用的功能,将其写成工具类

package com.atguigu.util;

import javax.servlet.http.Cookie;

public class CookieUtils {

/**
* 查找指定名称的Cookie对象
* @param name
* @param cookies
* @return
*/
public static Cookie findCookie(String name, Cookie[] cookies) {
if (name == null || cookies == null || cookies.length == 0) {
return null;
}

for (Cookie cookie : cookies) {
if (name.equals(cookie.getName())) {
return cookie;
}
}
return null;
}
}

Cookie值的修改

一种方法是服务器端创建一个同名的Cookie对象但赋予新的Cookie值,然后调用response.addCookie()

17-Cookie和Session_java_14

17-Cookie和Session_html_15

这就是之前提到的,浏览器收到响应发现有set-cookie的响应头,就去查看有没有这个cookie,没有就创建,有就修改它的值

17-Cookie和Session_java_16

另一种方法是找到要修改的cookie对象,调用setValue()赋予新的cookie值,然后调用response.addCookie()通知客户端保存修改

17-Cookie和Session_服务器_17

17-Cookie和Session_java_18

需要注意的一点是上面的两种方法,要修改的值中不应包含中文、空格、方括号...,如果有这个需求,则需要先对这个值进行BASE64编码


谷歌和火狐浏览器如何查看Cookie

17-Cookie和Session_html_19

17-Cookie和Session_html_20

Cookie的存活设置

指定cookie在什么时候被销毁,通过setMaxAge()设置,设置为正数时表示在指定秒数后过期,负数时表示关闭浏览器cookie即被删除(默认),零时表示立即删除cookie

17-Cookie和Session_服务器_21

17-Cookie和Session_java_22

Cookie的path属性

通过请求的地址来过滤哪些cookie发送给服务器,哪些不发。cookie默认的path是/工程路径

17-Cookie和Session_服务器_23

比如CookieA的path属性是 path=/工程路径,CookieB的是 path=/工程路径/abc,请求地址是http://ip:port/工程路径/a.html,此时发送CookieA,CookieB不发送;请求地址是http://ip:port/工程路径/abc/a.html,此时两个Cookie都发送

17-Cookie和Session_java_24

17-Cookie和Session_服务器_25

点击发送请求后,浏览器收到了发送过来的cookie

17-Cookie和Session_java_26

但没有看到这个cookie

17-Cookie和Session_java_27

当请求地址符合cookie的path属性时,该cookie被发送给服务器

17-Cookie和Session_html_28

练习:免用户名登录

17-Cookie和Session_java_29

login.jsp

17-Cookie和Session_java_30

package com.atguigu.servlet;

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");

if ("wzg168".equals(username) && "123456".equals(password)) {
Cookie cookie = new Cookie("username", username);
cookie.setMaxAge(60 * 60 * 24 * 7);
resp.addCookie(cookie);
System.out.println("登录成功");
} else {
System.out.println("登录失败");
}
}
}

web.xml

17-Cookie和Session_html_31

再次访问login.jsp时发送给服务器的cookie

17-Cookie和Session_服务器_32

什么是Session

HttpSession是Java中定义的一个接口,Session即会话,用来维护一个客户端与服务器的关联,每个客户端都有自己的一个Session会话,用来保存用户登录之后的信息,Session会话放在服务器端


Session的创建和获取

request.getSession(),第一次调用是创建Session会话,之后调用则是获取之前创建的Session会话对象。isNew()用来判断Session对象是不是刚创建出来的,true表示刚创建,false表示表示是之前创建。每个会话都有唯一的一个ID号,用来区分不同的会话。getId()获取会话的id值

session.html

17-Cookie和Session_服务器_33

package com.atguigu.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class SessionServlet extends BaseServlet {

protected void createOrGetSession(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
boolean isNew = session.isNew();
String id = session.getId();

resp.getWriter().write("session的id是:" + id + "<br />");
resp.getWriter().write("这个session是否是新创建的:" + isNew);
}
}

web.xml

17-Cookie和Session_java_34

第一次点击

17-Cookie和Session_html_35

第二次点击

17-Cookie和Session_java_36

Session域中数据的存取

17-Cookie和Session_html_37

17-Cookie和Session_服务器_38

Session超时的控制

setMaxInactiveInterval()设置session的超时时间,超过这个时间session就会被销毁,getMaxInactiveInterval()获取session超时时间,默认单位为秒

session默认超时时长为半小时

17-Cookie和Session_服务器_39

17-Cookie和Session_服务器_40

17-Cookie和Session_服务器_41

这是因为tomcat服务器的配置文件中配置了当前所有session的默认超时时长为30分钟

17-Cookie和Session_html_42

上面路径下的conf目录下的web.xml文件中

17-Cookie和Session_html_43

配置web工程下默认的session的超时时长,修改WEB-INF/web.xml,重启生效

17-Cookie和Session_服务器_44

修改指定session的超时时长

17-Cookie和Session_html_4517-Cookie和Session_java_46

点击Session3秒超时销毁会将当前session的超时时间设置为3秒,若不停点击session是否是新创建的,在经过3秒后应该会得到为true的结果,可实际是若一直点击,结果一直都是false,这说明经过3秒这个session并未被销毁。这是因为在这个session存在的时间内,若发起过请求,这个session的超时时间会被重置为设定的3秒。3秒内没有发起请求,再点击session是否为新创建的,就会得到true。所以session的超时时间指的是客户端两次发起请求的最大间隔时间

超时时间设置为负数表示session永不过时,极少设置为负数,因为不销毁session,会占用越来越多服务器内存

invalidate()可以让session立即超时失效

17-Cookie和Session_java_47

浏览器和Session之间关联的技术内幕

浏览器访问服务器后,在服务器端会创建一个session会话,但在该会话没有超时的时间段内,如果关闭浏览器再打开并访问服务器,会发现又创建了一个新的会话,这是因为关闭浏览器就是删除了第一个session的cookie

17-Cookie和Session_html_48