web_day37_cookie

一、相关概念

1、什么是会话?

HttpServletRequest对象和ServletContext对象都可以对数据进行保存,但是这两个对象都不可行,具体原因如下:

(1)客户端请求Web服务器时,针对每次HTTP请求,Web服务器都会创建一个HttpServletRequest对象,该对象只能保存本次请求所传递的数据。由于购买和结账是两个不同的请求,因此,在发送结账请求时,之前购买请求中的数据将会丢失。

(2)使用ServletContext对象保存数据时,由于同一个Web应用共享的是同一个ServletContext对象,因此,当用户在发送结账请求时,由于无法区分哪些商品是哪个用户所购买的,而会将该购物网站中所有用户购买的商品进行结算,这显然也是不可行的。

(3)为了保存会话过程中产生的数据,在Servlet技术中,提供了两个用于保存会话数据的对象,分别是Cookie和Session。关于Cookie和Session的相关知识,将在下面的小节进行详细讲解。

2、cookie和浏览器缓存的关系

浏览器缓存可以缓存任意内容(上网浏览的所有内容)

cookie只是服务器需要浏览器缓存数据(cookie只是浏览器缓存中一部分

3、会话技术的分类

  • 服务器端会话技术——session
  • 客户端会话技术——cookie

二、cookie

1、什么是cookie?

cookie一种由服务器生成(响应头Set-Cookie),保存在客户端(请求头Cookie)的会话跟踪技术

cookie技术它是基于http协议的!

2、cookie的作用

Cookie将用户的信息保存到客户端浏览器的一个技术,当用户下次访问的时候,浏览器会自动携带Cookie的信息过来到服务器端

3、cookie的执行原理

4、cookie操作相关的方法

4.1 创建cookie

Cookie cookie = new Cookie(String name,String value);

4.2 响应

response.addCookie(Cookie cookie);//将cookie发送给浏览器

4.3 获取

Cookie[] cookies = request.getCookies(); //接收浏览器携带的所有cookie

5、cookie的生命

cookie的默认生命是一个会话级别的,关闭浏览器就没了

设置cookie的存活时间

setMaxAge(int s);//设置 cookie 的最大生存时间,以秒为单位

追杀cookie

setMaxAge(0);

6、cookie的规范

  • cookie的规范是一个组织规定的
  • 单个的cookie的大小不超过4KB
  • 一个服务器最多可以向客户端浏览器保存20个cookie
  • 一个客户端浏览器最多保存300个Cookie
  • 在浏览器大战的今天,一些浏览器厂商为了抢夺客户,对cookie进行了扩容(也是有限度的),比如 8KB,100,500

7、cookie的路径

cookie的路径只与是否归还(归还的路径)有关,不能按照常规的路径去理解

cookie归还的路径:

  • 目前指的就是创建这个cookie的路径
  • cookie的默认路径就是当前创建这个cookie所在的Servlet的路径:端口之后servlet名称之前的这么一段
  • 例如:设置cookie的路径是/web_day37/cookie,那么包含/web_day37/cookie路径,都可以访问到(http://localhost:8080/web_day37/cookie/abc/BServlet
package com.itheima.web.servlet;

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

/**
 * 演示cookie路径问题
 *
 */
public class AServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 处理post请求中文乱码问题
		request.setCharacterEncoding("utf-8");
		// 处理响应的中文乱码问题
		response.setContentType("text/html;charset=utf-8");

		// 1.创建cookie
		Cookie cookie = new Cookie("msg", "hehe");

		// 2.设置cookie的声明周期
		cookie.setMaxAge(60 * 60 * 24 * 7);

		// 3.设置cookie的访问路径
		cookie.setPath("/web_day37/cookie");

		// 4.写回cookie
		response.addCookie(cookie);

	}

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

}

package com.itheima.web.servlet;

import java.io.IOException;
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 com.itheima.utils.CookieUtils;

/**
 * 获取cookie的值
 *
 */
public class BServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 处理post请求中文乱码问题
		request.setCharacterEncoding("utf-8");
		// 处理响应的中文乱码问题
		response.setContentType("text/html;charset=utf-8");

		// 1.获得所有的Cookie
		Cookie[] cookies = request.getCookies();
		// 2.获得指定cookie
		Cookie cookie = CookieUtils.getCookieByName("msg", cookies);
		// 3.非空判断
		if (cookie != null) {
			// 4.响应给浏览器
			response.getWriter().write(cookie.getValue());
		}
	}

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

}

8、cookie的域(domain)

cookie的数据(用户名和密码)

www.baidu.com

tieba.baidu.com

news.baidu.com

cookie的域主要解决二级域名携带cookie数据的问题!

cookie.setDomain(.baidu.com);
cookie.setpath("/");

应用场景

在百度首页登录成功一次之后,下次再访问百度新闻,会把第一次访问百度首页保存在cookie里面的数据(用户名和密码)携带过来,完成自动登录功能

9、cookie的乱码问题

  • cookie不能跨浏览器
  • cookie的name和value都不能使用中文,不支持中文
  • 解决:
    • 把中文转换成URL编码后才能创建cookie,发送到浏览器
    • 读取Cookie之后,还要使用URL解码
import java.io.IOException;
import java.net.URLEncoder;

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

/**
 * @ClassName: SetCookieServlet
 * @Description:向cookie中保存中文数据
 * @author jsz
 * @date 2018年8月12日
 */
public class SetCookieServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("utf-8");

		// 对请求的数据进行重新编码
		String username = URLEncoder.encode("姓名", "utf-8");
		String value = URLEncoder.encode("天明", "utf-8");

		// 创建cookie
		Cookie cookie = new Cookie(username, value);

		// 设置cookie的生命
		cookie.setMaxAge(60 * 60 * 24);

		// 响应cookie
		response.addCookie(cookie);

	}

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

}
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;

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 com.itheima.utils.CookieUtils;

/**
 * @ClassName: GetCookieServlet
 * @Description:从Cookie中获得中文数据
 * @author jsz
 * @date 2018年8月12日
 */
public class GetCookieServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("utf-8");
		// 1.获得所有Cookie
		Cookie[] cookies = request.getCookies();
		// 2.获得指定cookie
		String username = URLEncoder.encode("姓名", "utf-8");

		Cookie cookie = CookieUtils.getCookieByName(username, cookies);
		// 3.非空判断
		if (cookie != null) {
			String value = cookie.getValue();
			response.getWriter().write(URLDecoder.decode(value, "utf-8"));
		}
	}

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

}

案例

1、案例1:记录用户上次的访问时间

1.1 流程分析

1.2 实现

  • web层代码
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

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 com.itheima.utils.CookieUtils;

public class LastVisitTimeServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("utf-8");

		// 1.获取用户携带股票来的所有的cookie
		Cookie[] cookies = request.getCookies();

		// 2.获取最后一次访问时间的cookie
		Cookie cookie = CookieUtils.getCookieByName("lastvisttime", cookies);

		// 3.判断cookie
		if (cookie == null) {
			// 第一次访问,给一个提示信息
			response.getWriter().write("欢迎光临");

		} else {
			// 4.获取cookie的值
			String value = cookie.getValue();

			// 5.格式化时间
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
			String lastVistTime = sdf.format(new Date(Long.parseLong(value)));

			// 6.将上次访问的时间返回给客户端浏览器
			response.getWriter().write("<h3 style='color:blue'>客官,您上次访问的时间是:" + lastVistTime + "</h3>");
		}

		// 7.更新cookie的值
		Cookie cookie1 = new Cookie("lastvisttime", System.currentTimeMillis() + "");

		// 8.设置cookie的生命
		cookie1.setMaxAge(60 * 60 * 24);
		
		// 9.设置cookie的访问路径
		cookie1.setPath(request.getContextPath() + "/");

		// 10.将这个cookie响应给客户端浏览器
		response.addCookie(cookie1);
	}

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

}
  • 工具类
package com.itheima.utils;

import javax.servlet.http.Cookie;

public class CookieUtils {

	public static Cookie getCookieByName(String cookieName, Cookie[] cookies) {
		// 1.非空判断
		if (cookies != null) {
			// 2.遍历
			for (Cookie cookie : cookies) {
				// 3.判断(获得指定名称的)
				if (cookieName.equals(cookie.getName())) {
					// 4.返回
					return cookie;
				}
			}
		}
		return null;
	}
}

访问地址

http://localhost:8080/web_day37/LastVisitTimeServlet

案例2:展示用户的浏览历史

需求

当用户访问一个商品的时候,需要将该商品保留在浏览记录中

技术分析

cookie

步骤分析

  • 先将product_list.htm转成jsp
  • 点击一个商品,展示该商品的信息,将该商品id记录到cookie  (GetProductById)
  • 获取之前的浏览记录 例如名称:ids
    • 判断cookie是否为空
      • 若为空 将当前商品的id起个名称 ids 放入cookie中  ids=1
      • 若不为空,获取值 例如:ids=2-1  当前访问的id=1  使用"-"分割商品id
        • 判断之前记录中有无该商品
        • 若有,将当前的id放入最前面  结果 ids=1-2
        • 若没有,继续判断ids长度是否>=3
          • 若>=3,移除最后一个,将当前的id放入最前面
          • 若<3,直接将当前的id放入最前面
          • 若 ids=3-2-1 现在访问1 结果 ids=1-3-2
          • 若 ids=4-3-2 现在访问1 结果 ids=1-4-3
  • 再次回到product_list.jsp页面,需要将之前访问商品展示在浏览记录中
    • 获取ids  例如:ids=2-3-1
    • 切割
import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

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 com.itheima.utils.CookieUtils;

/**
 * 记录商品浏览器历史
 */
public class GetProductByIdServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//0.设置编码
		//0.1获取当前访问的商品id
		String id=request.getParameter("id");
		
		//1.获取指定的cookie ids
		Cookie c = CookieUtils.getCookieByName("ids", request.getCookies());
		
		String ids="";
		//2.判断cookie是否为空
		if(c==null){
			//若cookie为空  需要将当前商品id放入ids中
			ids=id;
		}else{
			//若cookie不为空 继续判断ids中是否已经该id // ids=2-11-
			//获取值
			ids=c.getValue();
			String[] arr = ids.split("-");
			//将数组转成集合  此list长度不可变
			List<String> asList = Arrays.asList(arr);
			//将aslist放入一个新list中
			LinkedList<String> list = new LinkedList<>(asList);
			
			if(list.contains(id)){
				//若ids中包含id  将id移除 放到最前面
				list.remove(id);
				list.addFirst(id);
			}else{
				//若ids中不包含id  继续判断长度是否大于2
				if(list.size()>2){
					//长度>=3 移除最后一个 将当前的放入最前面
					list.removeLast();
					list.addFirst(id);
				}else{
					//长度<3 将当前放入最前面
					list.addFirst(id);
				}
			}
			
			ids="";
			//将list转成字符串
			for (String s : list) {
				ids+=(s+"-");
			}
		
			//ids=ids.substring(0, ids.length()-1);
		}
		
		//将ids写回去
		c=new  Cookie("ids",ids);
		//设置访问路径
		c.setPath(request.getContextPath()+"/");
		//设置存活时间
		c.setMaxAge(3600);
		
		//写回浏览器
		response.addCookie(c);
		
		
		//3.跳转到指定的商品页面上
		response.sendRedirect(request.getContextPath()+"/product_info"+id+".htm");
		
	}

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

}

案例3:清空历史记录

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

/**
 *清空浏览记录
 */
public class ClearHistroyServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//创建一个cookie
		Cookie c=new Cookie("ids", "");
		c.setPath(request.getContextPath()+"/");//   /day1101/
		
		//设置时间
		c.setMaxAge(0);
		
		//写回浏览器
		response.addCookie(c);
		
		//页面跳转
		response.sendRedirect(request.getContextPath()+"/product_list.jsp");
	}

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

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值