Cookie、Session

  • Cookie
  • 介绍
  • Cookie 的创建
  • Cookie 的获取
  • Cookie 的修改
  • Cookie 的存活控制
  • Cookie 的 path 路径
  • 免密登录练习
  • Session
  • 介绍
  • Session 的创建
  • 数据的存取
  • Session 的生命周期


Cookie

cookie.jsp

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Cookie</title>
<base href="http://localhost:8080/cookieAndsession/" />
<style type="text/css">

	ul li {
		list-style: none;
	}
	
</style>
</head>
<body>
	<iframe name="target" width="500" height="500" style="float: left;"></iframe>
	<div style="float: left;">
		<ul>
			<li><a href="cookieServlet?action=createCookie" target="target">Cookie的创建</a></li>
			<li><a href="cookieServlet?action=getCookie" target="target">Cookie的获取</a></li>
			<li><a href="cookieServlet?action=updateCookie" target="target">Cookie值的修改</a></li>
			<li>Cookie的存活周期</li>
			<li>
				<ul>
					<li><a href="cookieServlet?action=defaultLife" target="target">Cookie的默认存活时间(会话)</a></li>
					<li><a href="cookieServlet?action=deleteNow" target="target">Cookie立即删除</a></li>
					<li><a href="cookieServlet?action=live" target="target">Cookie存活3600秒(1小时)</a></li>
				</ul>
			</li>
			<li><a href="cookieServlet?action=cookiePath" target="target">Cookie的路径设置</a></li>
			<li><a href="" target="target">Cookie的用户免登录练习</a></li>
		</ul>
	</div>
</body>
</html>

介绍

  1. Cookie 是服务器发送给客户端,并保存在客户端键值对形式的数据。
  2. 客户端保存的 Cookie ,在每次向服务器发送请求时,都会发送给服务器。
  3. 每个 Cookie 的大小不能超过 4kb。

Cookie 的创建

/**
	 * Cookie的创建
	 * @param req
	 * @param resp
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//1.创建Cookie对象
		Cookie cookie1 = new Cookie("key1", "value1");
		Cookie cookie2 = new Cookie("key2", "value2");
		//2.通知客户端(即浏览器)保存Cookie
		resp.addCookie(cookie1);//底层源码是在响应头中设置set-cookie: key=value实现
		resp.addCookie(cookie2);//底层源码是在响应头中设置set-cookie: key=value实现
		resp.getWriter().write("Cookie创建成功");
	}

Cookie 的获取

/**
	 * Cookie的获取
	 * @param req
	 * @param resp
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//1.获取浏览器Cookie
		Cookie[] cookies = req.getCookies();
		for(Cookie c : cookies) {
			//getName()		获取Cookie的key
			//getValue()	获取Cookie的value
			resp.getWriter().write("key="+c.getName()+", value="+c.getValue()+"<br/>");
		}
		//2.获取满足条件的Cookie
		Cookie cookie = CookieUtils.getCookie(cookies, "key1");
		if(cookie!=null) {
			resp.getWriter().write("查询到指定的Cookie");
		}
	}

CookieUtils.java

package cookie.utils;

import javax.servlet.http.Cookie;

public abstract class CookieUtils {
	/**
	 * 查找满足条件的Cooike
	 * @return
	 */
	public static Cookie getCookie(Cookie[] cookies, String name) {
		if(cookies==null || cookies.length==0 || name==null || name=="") {
			return null;
		}
		for(Cookie cookie : cookies) {
			if(name.equals(cookie.getName())) {
				return cookie;
			}
		}
		return null;
	}
}

Cookie 的修改

/**
	 * Cookie的修改
	 * @param req
	 * @param resp
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//修改Cookie值的两种方法
		//方案1:
		//1.创建Cookie对象,key设置为想要修改的Cookie的相同key,value设置为新value,假设要将key1的值修改为value3
		Cookie cookie1 = new Cookie("key1", "value3");
		//2.保存到浏览器
		resp.addCookie(cookie1);
		
		//方案2:
		//1.查找需要修改的Cookie对象,假设将key2的值修改为value4
		Cookie cookie2 = CookieUtils.getCookie(req.getCookies(), "key2");
		if(cookie2!=null) {
			//2.调用setValue()方法赋于新的Cookie值
			cookie2.setValue("key4");
			//3.调用addCookie()保存修改
			resp.addCookie(cookie2);
			resp.getWriter().write("Cookie已修改");
			/**
			 * 注意:setValue(String name)方法不支持中文,以及特殊字符,只支持英文,如果想设置上述字符,需要使用Base64编码
			 * 但直接设置中文也能显示...
			 */
			//cookie2.setValue(new String(Base64.getEncoder().encode("新value".getBytes())));
			//cookie2.setValue("新value");
			//resp.addCookie(cookie2);
		}
	}

Cookie 的存活控制

  • setMaxAge(int i):i 以秒为单位
  • 正数,表示在指定的秒数后销毁
  • 负数,表示当浏览器关闭时销毁,Cookie创建时默认值为 -1
  • 零,表示立即删除该Cookie
/**
	 * 演示默认情况下的Cookie生存时间
	 * @param req
	 * @param resp
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void defaultLife(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		Cookie cookie = new Cookie("defaultLife", "defaultLife");
		cookie.setMaxAge(-1);
		resp.addCookie(cookie);
		resp.getWriter().write("演示Cookie的默认存活时间");
	}
	/**
	 * 演示立即删除Cookie
	 * @param req
	 * @param resp
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		Cookie cookie = CookieUtils.getCookie(req.getCookies(), "key1");
		if(cookie!=null) {
			cookie.setMaxAge(0);
			resp.addCookie(cookie);
			resp.getWriter().write("Cookie已删除");
		}
	}
	/**
	 * 设置Cookie存活3600s
	 * @param req
	 * @param resp
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void live(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		Cookie cookie = new Cookie("live", "live");
		cookie.setMaxAge(3600);
		resp.addCookie(cookie);
		resp.getWriter().write("设置Cookie存活3600s");
	}

Cookie 的 path 路径

Cookie 的 path 属性可以过滤 Cookie,只有满足 path 条件的 Cookie 才会发送给服务器,不设置 path 时,默认 path 是工程路径。

假设:
CookieA path="/工程路径"
CookieB path="/工程路径/abc"

请求地址为:
http://ip:port/工程路径/a.html CookieA 发送
CookieB 不发送

请求地址为:
http://ip:port/工程路径/abc/a.html CookieA 发送
CookieB 发送

/**
	 * 演示设置Cookie的path
	 * @param req
	 * @param resp
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void cookiePath(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		Cookie cookie = new Cookie("cookie_path", "cookie_path");
		//只有访问到工程路径下的cookiePath目录时,才会向浏览器发送这个cookie
		//不设置path时,默认path是工程路径下
		cookie.setPath(req.getContextPath() + "/cookiePath");
		resp.addCookie(cookie);
		resp.getWriter().write("创建有path的Cookie");
	}

免密登录练习

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>login</title>
<base href="http://localhost:8080/cookieAndsession/">
</head>
<body>
	<form action="loginServlet" method="get">
		<input type="hidden" name="action" value="login">
		用户名:<input type="text" name="username" value="${ cookie.username.value }" /><br/>
		密码:<input type="password" name="password" /><br/>
		<input type="submit" value="登录" />
	</form>
</body>
</html>

LoginServlet.java

package cookie.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginServlet extends BaseServlet{
	private static final long serialVersionUID = 1L;
	
	protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String username = req.getParameter("username");
		String password = req.getParameter("password");
		if("admin".equals(username) && "admin".equals(password)) {
			Cookie cookie = new Cookie("username", username);
			cookie.setMaxAge(60 * 60 * 24);
			resp.addCookie(cookie);
			System.out.println("登录成功");
		} else {
			System.out.println("登录失败");
		}	
	}	
}

Session

session.jsp

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Session</title>
<base href="http://localhost:8080/cookieAndsession/">
<style type="text/css">

	ul li {
		list-style: none;
	}
	
</style>
</head>
<body>
	<iframe name="target" width="500" height="500" style="float: left;"></iframe>
	<div style="float: left;">
		<ul>
			<li><a href="sessionServlet?action=getSession" target="target">Session的创建和获取(id号、是否为新创建)</a></li>
			<li><a href="sessionServlet?action=saveData" target="target">Session域数据的存储</a></li>
			<li><a href="sessionServlet?action=getData" target="target">Session域数据的获取</a></li>			
			<li>Session的存活</li>
			<li>
				<ul>
					<li><a href="sessionServlet?action=defaultTimeout" target="target">Session的默认超时及配置</a></li>
					<li><a href="sessionServlet?action=setTimeout" target="target">Session3秒超时销毁</a></li>
					<li><a href="sessionServlet?action=immediateTimeout" target="target">Session马上销毁</a></li>
				</ul>
			</li>
			<li><a href="" target="target">浏览器和Session绑定的原理</a></li>
		</ul>
	</div>
</body>
</html>

介绍

  1. Session 是一个接口(HttpSession)。
  2. Session ,会话,用来维护客户端和服务器之间关联的一种技术。
  3. 每个客户端都有自己的 Session 会话。
  4. Session 经常用来保存用户登录之后的信息。

Session 的创建

创建Session:

  1. request.getSession()
    第一次调用是:创建Session对象
    之后调用都是:获取前面创建好的Session对象
  2. Session对象方法:
    isNew():判断当前Session对象是否是新创建的
    true 表示刚创建
    false 表示获取之前创建的
    getId():获取Session的id值。
    每个会话都有一个ID值,而且这个ID是唯一的
/**
	 * 演示创建于 以及获取Session
	 * @param req
	 * @param resp
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void getSession(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//1.获取Session对象
		HttpSession session = req.getSession();
		//2.判断Session是新创建的还是获取之前创建好的
		boolean flag = session.isNew();
		//3.获取当前Session的ID值
		String id = session.getId();//第一次为true,之后为false
		//在浏览器内显示
		resp.getWriter().write("当前Session的ID为:" + id + "\n是否为新创建:" + flag);
	}

数据的存取

  1. 将数据存储到Session域
/**
	 * 将数据存储到Session域
	 * @param req
	 * @param resp
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void saveData(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		HttpSession session = req.getSession();
		session.setAttribute("key", "session");
		resp.getWriter().write("数据保存到Session域成功");
	}
  1. 获取Session域中的数据
/**
	 * 获取Session域中的数据
	 * @param req
	 * @param resp
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void getData(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		HttpSession session = req.getSession();
		Object attr = session.getAttribute("key");
		resp.getWriter().write("获取Session域中数据成功" + ": key=" + attr);
	}

Session 的生命周期

Session的超时指的是两次请求之间的最大时间间隔。

方法

意义

public int getMaxInactiveInterval()

获取Session的超时时间

public void setMaxInactiveInterval(int interval)

设置Session的超时时间(以秒为单位)

public void invalidate()

让当前Session会话立即超时无效

超过指定的时长,Session就会被销毁,值为正数的时候,设定 Session 的超时时长,负数表示永远不超时(极少使用)

/**
	 * 演示Tomcat中Session的默认超时时间
	 * @param req
	 * @param resp
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void defaultTimeout(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		HttpSession session = req.getSession();
		int maxInactiveInterval = session.getMaxInactiveInterval();//1800s(30min)
		resp.getWriter().write("默认的超时时间为:" + maxInactiveInterval);
		/**
		 * 一般不修改Tomcat的默认超时时间,
		 * 但可以在web.xml配置文件中,设置当前工程的默认超时时间,以min为单位
		 */
	}
	/**
	 * 设置当前会话的超时时间
	 * @param req
	 * @param resp
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void setTimeout(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		HttpSession session = req.getSession();
		session.setMaxInactiveInterval(3);
		resp.getWriter().write("已设置当前会话的超时时间为3s");
	}
	/**
	 * 让当前Session会话立即超时无效
	 * @param req
	 * @param resp
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void immediateTimeout(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		HttpSession session = req.getSession();
		session.invalidate();
		resp.getWriter().write("已设置当前会话立即超时无效");
	}