保存在客户端:服务器主动保存在客户端浏览器特定目录下的小文件
Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。
cookie 是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。 cookie由服务器生成,发送给浏览器,浏览器把cookie以 K-V 形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该cookie发送给服务器。由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的cookie数量是有限的。
由于HTTP是一种无状态的协议,它不对之前发送过的请求和响应的状态进行管理。服务器单从网络连接上无从知道客户身份。也就是说,无法根据之前的状态进行本次的请求处理。假设要求登录认证的 Web 页面本身无法进行状态的管理(不记录已登录的状态),那么每次跳转新页面不是要再次登录,就是要在每次请求报文中附加参数来管理登录状态。 无状态协议当然也有它的优点。由于不必保存状态,自然可减少服务器的 CPU 及内存资源的消耗。从另一侧面来说,也正是因为 HTTP 协议本身是非常简单的,所以才会被应用在各种场景里。
如果让服务器管理全部客户端状态则会成为负担,保留无状态协议这个特征的同时又要解决类似的矛盾问题,于是引入了 Cookie 技术。Cookie 技术通过在请求和响应报文中写入Cookie信息来控制客户端的状态。
Cookie会根据从服务器端发送的响应报文内的一个叫做Set-Cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入Cookie 值后发送出去。
给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
-
Servlet
@WebServlet(urlPatterns= "/demoServlet") public class DemoServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Cookie[] cookies = req.getCookies();//获取客户端访问时提交过来的Cookie Arrays.stream(cookies).forEach(System.out::println); Arrays.stream(cookies).forEach((item)-> System.out.println(item.getName()+" "+item.getValue())); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie cookie = new Cookie("name","lisi"); response.addCookie(cookie); //将Cookie发送到客户端浏览器 request.getRequestDispatcher("/index.jsp").forward(request,response); } }
-
Jsp页面
Hello World!
-
运行: 首先在浏览器中请求http://localhost:8080/demoServlet,打开浏览器发现:
然后单击打开的index.jsp页面中的按钮,发现控制台中输出:
当用户选中记住登录状态复选框时,在服务器端做逻辑判断:获取COOKIE,查看里面的用户名和密码是否在数据库中,如果在登录成功,否则提示登录。
-
用户登录页面
login 用户名: 密码: 保持登录一周:
-
LoginServlet.java
@WebServlet(urlPatterns = "/loginServlet") public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String jiZhu = request.getParameter("jiZhu"); String uname = request.getParameter("uname"); String upwd = request.getParameter("upwd"); if ("zhangsan".equals(uname) && "1234".equals(upwd)) {//如果登录成功 if ("jiZhu".equals(jiZhu)) {//用户选择了记住登录状态 Cookie cookie = new Cookie("user", uname + ":" + upwd); cookie.setMaxAge(60*60*24*7);//Cookie保存时间一周 response.addCookie(cookie);//将Cookie信息发送到客户端 } request.getRequestDispatcher("/index.jsp").forward(request, response); //打开首页 } } }
-
index.jsp
Hello World!
-
DemoServlet.java
@WebServlet(urlPatterns = "/demoServlet") public class DemoServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { boolean flag = false;//表示用户未登录 Cookie[] cookies = request.getCookies();//获取用户提交过来的所有Cooki if (cookies == null) { request.getRequestDispatcher("/login.jsp").forward(request, response); return; } for (Cookie item : cookies) { if ("user".equals(item.getName())) {//zhangsan:1234 String[] values = item.getValue().split(":"); if ("zhangsan".equals(values[0]) && "1234".equals(values[1])) {//Cookie信息正确,登录成功 flag = true; break; //不需要再进行后面的判断了 } } } if (flag) {//已经有登录信息,打开主页 request.getRequestDispatcher("/index.jsp").forward(request, response); } else {//跳转到登录页面 request.getRequestDispatcher("/login.jsp").forward(request, response); } } }
-
运行 1、打开index.jsp页面,单击提交按钮
2、单击提交按钮,进入断点:
3、因为Cookie中没有user,所以打开login.jsp
4、依次输入用户名和密码,但不选择记住密码,然后单击按钮:
5、打开index.jsp页面:
6、单击提交按钮,进入Debug,判断Cookie中有值,不再需要登录,直接进入login.jsp页面
7、最终程序进入index.jsp页面