JavaWeb之Cookie

一、会话的概念:

  • 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。
  • HTTP协议是一种无状态协议,在数据交换完毕后,服务器端和客户端的链接就会关闭,每次交换数据都需要建立新的链接。
  • Cookie的作用是储存在用户本地终端上的数据,也可以叫做浏览器缓存。
  • 有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾经来过,这称之为有状态会话。
  • Cookie的应用场景
    1.记录用户登录网址的次数
    2.商品浏览记录
    3.自动登录
    4.电商购物车功能

二、保存会话的两种技术:

  • Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。

  • Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。

三、Cookie常用API介绍:

方法 作用
Cookie(String name, String value) 构造带指定名称和值的 cookie。
public String getName() 返回 cookie 的名称。名称在创建之后不得更改。
public String getValue() 返回 cookie 的值。
public void setValue(String newValue) 在创建 cookie 之后将新值分配给 cookie
public void setMaxAge(int expiry) 正值表示 cookie 将在经过该值表示的秒数后过期。注意,该值是 cookie 过期的最大 生存时间,不是 cookie 的当前生存时间。负值意味着 cookie 不会被持久存储,将在 Web 浏览器退出时删除。0 值会导致删除 cookie(1、如果在服务器端没有调用setMaxAge方法设置cookie的有效期,那么cookie的有效期只在一次会话过程中有效,当用户关闭浏览器,会话就结束了,此时cookie就会失效2、如果在服务器端使用setMaxAge方法设置了cookie的有效期,比如设置了30分钟,那么当服务器把cookie发送给浏览器时,此时cookie就会在客户端的硬盘上存储30分钟,在30分钟内,即使浏览器关了,cookie依然存在,在30分钟内,)
public int getMaxAge() 返回以秒为单位指定的 cookie 的最大生存时间,默认情况下,-1 指示该 cookie 将保留到浏览器关闭为止。
public void setPath(String uri) 指定客户端应该返回 cookie 的路径。
public String getPath() 返回浏览器将此 cookie 返回到的服务器上的路径。cookie 对于服务器上的所有子路径都是可见的
public void setDomain(String pattern) 指定应在其中显示此 cookie 的域。
public String getDomain() 返回为此 cookie 设置的域名。域名形式是根据 RFC 2109 设置的。

补充:
1、public Cookie[] getCookies();返回包含客户端随此请求一起发送的所有 Cookie 对象的数组。如果没有发送任何 cookie,则此方法返回 null
2、response接口也中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。

四、Cookie的使用案例:

自定义的CookieUtil包:

/**
 * @author 追梦逐星
 * @param  Cookie[]	Cookie类型的数组
 *  	   String 	类型的name
 * @return Cookie
 *
 */
public class CookieUtil {
	// 根据得到的cookie数组得到自己想要的那个cookie对象
	public static Cookie getCookieByName(Cookie[] cookies, String name) {
		if (cookies == null) {
			return null;
		}		
		for (Cookie cookie : cookies) {
			if (name.equals(cookie.getName())) {
				return cookie;
			}
		}
		return null;
	}
}

案例一、简单的创建一个Cookie,并获得设置的值

FirstCookieServlet.java用来创建一个Cookie对象,并向其里面存值。

public class FirstCookieServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 1、创建一个Cookie
		Cookie cookie = new Cookie("goods", "iphone-XS");
		// 2、将创建的cookie对象返回给浏览器
		response.addCookie(cookie);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}

SecondCookieServlet.java用来获取FirstCookieServlet.java中存入的值:

public class SecondCookieServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 得到Cookie对象,返回的是一个Cookie数组
		Cookie[] cookies = request.getCookies();
		// 得到自己想要的cookie对象,并取出cookie中的信息
		Cookie cookie = getCookieByName(cookies, "goods");
		if(cookie !=null){
			response.getWriter().write(cookie.getValue());
		}else{
			response.getWriter().write("no cookie");
		}
	}
	
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		doGet(request, response);
	}
	//可以将其抽成Util类
	// 根据得到的cookie数组得到自己想要的那个cookie对象
	public Cookie getCookieByName(Cookie[] cookies, String name) {
		if (cookies == null) {
			return null;
		} else {
			for (Cookie cookie : cookies) {
				if (name.equals(cookie.getName())) {
					return cookie;
				}
			}
		}
		return null;
	}
}

案例二、记录用户上次访问该网页的时间

  • 将每一个会话作为一次访问过程,将每次会话的开始时间作为每次访问网站的时间,然后将这个时间以Cookie的形式存储到客户端的计算机中,客户端进行下次访问时通过该Cookie回传上次访问站点的时间值
public class TimeCookieServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		// 得到一个Cookie对象
		Cookie[] cookies = request.getCookies();
		// 找到名称为time的cookie对象
		Cookie time = CookieUtil.getCookieByName(cookies, "time");
		//格式化日期    IE  chrome Firefox不能包含逗号(,)空格( )分号(;)$开头的特殊字符
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
		// 如果为空说明会是第一次访问
		if (time == null) {
			response.getWriter().write("第一次的访问时间是:" + sdf.format(new Date()));
			time = new Cookie("time", sdf.format(new Date()));//方式一
		} else {
			response.getWriter().write("上一次的访问时间是:" + time.getValue());
			time.setValue(sdf.format(new Date()));//方式一
		}
		// 无论是第一次还是第几次都需要将得到的现在的时间存储到名为time的Cookie中
		//方式二、time = new Cookie("time", sdf.format(new Date()));
		System.out.println(sdf.format(new Date()));
		//time.setMaxAge(0);
		response.addCookie(time);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		doGet(request, response);
	}

}

案例三、实现用户对商品的浏览记录

三个jsp页面分别是:
展示商品列表的BookStore1.jsp
展示浏览过的商品列表ShowBook1.jsp
清除浏览过的商品列表CleanCookie1.jsp
一个Servlet,实现业务逻辑:
HistoryCookie1.java
1、为每一个商品链接添加id值
2、通过用户点击商品链接将id值传入到HistoryCookie1java
3、使用字符串将id值以-的形式进行连接,存储到Cookie中
4、在取出Cookie的值得时候,以-的形式进行分割
5、模仿数据库从字符串数组中取出对应的数据,并展示出来
代码展示:
BookStore1.jsp 展示商品列表

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>图书商城</title>
</head>
<body>
	<!--	图书列表	  -->
	图书列表:
	<br>
	<a href="/day06/history1?id=1">javaWeb实战开发</a>
	<br>
	<a href="/day06/history1?id=2">jdbc开发</a>
	<br>
	<a href="/day06/history1?id=3">Sping项目实战开发</a>
	<br>
	<hr>
	<a href="/day06/ShowBook1.jsp">查看浏览记录</a>
	<br>
	<a href="/day06/cleanCookie1.jsp">清除浏览记录</a>
	<br>

</body>
</html>

ShowBook1.jsp 展示浏览过的商品列表

<%@page import="com.syj.CookieUtil.CookieUtil"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>浏览记录展示</title>
</head>
<body>
	<%
		String[] books = { "javaWeb实战开发", "jdbc开发", "Sping项目实战开发" };
		Cookie[] cookies = request.getCookies();
		Cookie historyCookie = CookieUtil.getCookieByName(cookies, "historyCookie");
		if (historyCookie == null) {
	%>
	暂无商品浏览记录
	<%
		} else {
			String[] st = historyCookie.getValue().split("-");
			for (int i = 0; i < st.length; i++) {
	%>
	<%=books[Integer.parseInt(st[i]) - 1]%><br>
	<%
		}
		}
	%>
	<a href="/day06/BookStore1.jsp">返回商品购物页面</a>
</body>
</html>

CleanCookie1.jsp 清除浏览过的商品列表

<%@page import="com.syj.CookieUtil.CookieUtil"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>清空浏览记录</title>
</head>
<body>
	<%
		Cookie[] cookies = request.getCookies();
		Cookie cookie = CookieUtil.getCookieByName(cookies, "historyCookie");
		cookie.setMaxAge(0);
		cookie.setPath("/");
		response.addCookie(cookie);
	%>
	清除浏览记录成功
	<a href="/day06/BookStore1.jsp">返回商品购物页面</a>
</body>
</html>

HistoryCookie1.java 实现对浏览过的商品添加到cookie中

public class HistoryCookie1 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		response.setCharacterEncoding("UTF-8");
		// 1.获得商品的id值
		String id = request.getParameter("id");
		// 2.获得cookie集合
		Cookie[] cookies = request.getCookies();
		// 3.得到商品的cookie
		Cookie historyCookie = CookieUtil.getCookieByName(cookies, "historyCookie");
		if (historyCookie == null) {
			// 4、如果为空说明是第一次访问可以直接将id添加到cookie中
			historyCookie = new Cookie("historyCookie", id);
		} else {
			// 5、如果不为空说明已经存在了浏览记录
			// 5.1得到cookie值:按"-"进行连接
			String ids = historyCookie.getValue();
			String[] st = ids.split("-");
			// 5.2将st的字符串数组转化成List集合
			List<String> list = Arrays.asList(st);
			if (!list.contains(id)) {
				ids += "-" + id;
			}
			// 更新Cookie的值
			historyCookie = new Cookie("historyCookie", ids);
		}
		historyCookie.setMaxAge(24 * 60 * 60 * 7);
		historyCookie.setPath("/");
		response.addCookie(historyCookie);

		response.getWriter().write("访问成功,如果需要继续访问<a href='/day06/BookStore1.jsp'>请点击继续</a>");
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		doGet(request, response);
	}
}

平时的小知识积累,在此以笔记的形式记录下来,如有错误欢迎指正
不积跬步,无以至千里;不积小流,无以成江海

;