WEB开发会话技术02

6.Cookie的生命周期

默认情况下,Cookie只在浏览器的内存中存活,也就是说,当你关闭浏览器后,Cookie就会消失。但是也可以通过方法设置cookie的生存时间。

cookie的生命周期指的是如何管理cookie,什么时候cookie被销毁。

  • setMaxAge(int expiry):设置 cookie 的最大生存时间,以秒为单位

    • 整数:表示在指定的秒数后过期
    • 负数:表示浏览器关闭,cookie就会被删除(默认值是-1)
    • 0,表示马上删除cookie

6.1cookie生命周期expiry>0

CookieLive:

  1. package com.li.cookie;
  2. import javax.servlet.*;
  3. import javax.servlet.http.*;
  4. import javax.servlet.annotation.*;
  5. import java.io.IOException;
  6. import java.io.PrintWriter;
  7. @WebServlet(urlPatterns = {"/CookieLive"})
  8. public class CookieLive extends HttpServlet {
  9. @Override
  10. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  11. doPost(request, response);
  12. }
  13. @Override
  14. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  15. System.out.println("CookieLive doPost被调用...");
  16. //创建一个cookie,生命周期为 60s
  17. Cookie cookie = new Cookie("job", "java");
  18. //1.从创建改cookie开始计时,60秒后就无效
  19. //2.由浏览器来根据创建的时间来开始计时,到时间后就认为该cookie无效
  20. //3.如果该cookie无效了,那么浏览器在发出HTTP请求时,就不会带上该cookie
  21. cookie.setMaxAge(60);
  22. //将cookie保存到浏览器
  23. response.addCookie(cookie);
  24. //给浏览器返回信息
  25. response.setContentType("text/html;charset=utf-8");
  26. PrintWriter writer = response.getWriter();
  27. writer.print("<h1>设置cookie生命周期成功</h1>");
  28. writer.flush();
  29. writer.close();
  30. }
  31. }
  1. 在浏览器中访问该servlet:

  2. 可以看到该cookie的创建时间是 "Sun, 20 Nov 2022 14:15:39 GMT"

    真实时间为上述时间再加八小时

  3. 超过60s后,再去访问Tomcat服务器:(代码见4.2)

    在浏览器发送的HTTP请求中的Cookie字段已经没有了设置的cookie:

说明:由浏览器来根据创建的时间来开始计时,到时间后就认为该cookie无效。如果该cookie无效了,那么浏览器在发出HTTP请求时,就不会带上该cookie。

但是此时cookie没有被删除,在关闭浏览器的时候才会被删除。

6.2演示删除cookie(expiry=0)

删除下图名为username的cookie

  1. package com.li.cookie;
  2. import javax.servlet.*;
  3. import javax.servlet.http.*;
  4. import javax.servlet.annotation.*;
  5. import java.io.IOException;
  6. import java.io.PrintWriter;
  7. @WebServlet(urlPatterns = {"/cookieLive"})
  8. public class CookieLive extends HttpServlet {
  9. @Override
  10. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  11. doPost(request, response);
  12. }
  13. @Override
  14. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  15. //演示删除一个cookie
  16. //1.先得到usernameCookie
  17. Cookie[] cookies = request.getCookies();
  18. Cookie usernameCookie =
  19. CookieUtils.readCookieByName("username", cookies);
  20. if (usernameCookie != null) {
  21. //2.将其生命周期设置为0
  22. usernameCookie.setMaxAge(0);
  23. //3.重新保存该cookie,因为你将其生命周期设置为0,就等价于让浏览器删除该cookie
  24. response.addCookie(usernameCookie);//在响应体的Set-Cookie
  25. } else {
  26. System.out.println("没有找到该cookie");
  27. }
  28. //给浏览器返回信息
  29. response.setContentType("text/html;charset=utf-8");
  30. PrintWriter writer = response.getWriter();
  31. writer.print("<h1>设置cookie生命周期成功</h1>");
  32. writer.flush();
  33. writer.close();
  34. }
  35. }

redeployTomcat,浏览器访问该servlet,点击查看HTTP响应包:可以看到响应包中设置了该cookie的过期时间为1970年,这意味着浏览器将立即删除该cookie。

  1. Set-Cookie: username=jack; Expires=Thu, 01-Jan-1970 00:00:10 GMT

  2. 点击查看cookie存储,可以发现该cookie已经被删除了

说明:setMaxAge()方法设置参数为零时,当浏览器接收到服务器的响应包时,会立即删除该cookie。

6.3默认生命周期(expiry<0)

如果没有设置setMaxAge,或者setMaxAge的设置参数为负数,那么默认创建的cookie是会话级别的(即关闭浏览器就销毁了)

7.Cookie的有效路径

cookie有效路径Path的设置:

  1. Cookie的path属性,可以有效地过滤哪些Cookie可以发送给服务器,哪些不发。path属性是通过请求的URL地址来进行有效地过滤

  2. 规则如下:

    cookie1.setPath=/工程路径 cookie2.setPath=/工程路径/aaa

    1. 若请求地址为:http://ip:port/工程路径/资源

      cookie1发送给服务器

      cookie2不会发送给服务器
    2. 若请求地址为:http://ip:port/工程路径/aaa/资源

      cookie1发送给服务器

      cookie2发送给服务器

    即如果请求的url的地址包含了cookie设置的有效路径,则这个cookie就会被发送给服务器。

    说明:如果没有设置cookie的有效路径,默认就是 /工程路径

演示Cookie的有效路径的使用

  1. package com.li.cookie;
  2. import javax.servlet.*;
  3. import javax.servlet.http.*;
  4. import javax.servlet.annotation.*;
  5. import java.io.IOException;
  6. import java.io.PrintWriter;
  7. @WebServlet(urlPatterns = {"/cookiePath"})
  8. public class CookiePath extends HttpServlet {
  9. @Override
  10. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  11. doPost(request, response);
  12. }
  13. @Override
  14. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  15. System.out.println("cookiePath doPost被调用");
  16. //1.创建两个cookie
  17. Cookie cookie = new Cookie("address", "beijing");
  18. Cookie cookie2 = new Cookie("salary", "20000");
  19. //2.设置不同的有效路径
  20. //request.getContextPath()=/application context
  21. cookie.setPath(request.getContextPath());//有效路径=/cs
  22. cookie2.setPath(request.getContextPath() + "/aaa");//有效路径=/cs/aaa
  23. //3.保存到浏览器
  24. response.addCookie(cookie);
  25. response.addCookie(cookie2);
  26. //4.给浏览器回送提示信息
  27. response.setContentType("text/html;charset=utf-8");
  28. PrintWriter writer = response.getWriter();
  29. writer.print("<h1>设置cookie有效路径成功</h1>");
  30. writer.flush();
  31. writer.close();
  32. }
  33. }

如下,访问http://localhost:8080/cs/cookiePath,创建了address和salary两个cookie并设置了不同的有效路径

现在来访问http://localhost:8080/cs/xxx,抓包如下:

在来访问http://localhost:8080/cs/aaa/xxx

8.练习

完成自动填写登录账户案例,如果用户登录成功,则下次登录自动填写登录账户。

  1. 如果用户名是olien,密码是1234。则认为该用户合法,登录成功,否则失败。
  2. 要求实现:如果登录成功,则该用户在三天内登录可以自动填写其登录名。

CookieUtils:

  1. package com.li.cookie;
  2. import javax.servlet.http.Cookie;
  3. public class CookieUtils {
  4. //编写一个方法,返回指定名字的cookie值
  5. public static Cookie readCookieByName(String name, Cookie[] cookies) {
  6. //判断传入的参数是否正确
  7. if (name == null || "".equals(name) || cookies == null || cookies.length == 0) {
  8. return null;
  9. }
  10. //否则,就遍历cookies
  11. for (Cookie cookie : cookies) {
  12. if (name.equals(cookie.getName())) {
  13. return cookie;
  14. }
  15. }
  16. return null;
  17. }
  18. }

loginServlet:

  1. package com.li.cookie;
  2. import javax.servlet.*;
  3. import javax.servlet.http.*;
  4. import javax.servlet.annotation.*;
  5. import java.io.IOException;
  6. import java.io.PrintWriter;
  7. @WebServlet(urlPatterns = {"/login"})
  8. public class Login extends HttpServlet {
  9. @Override
  10. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  11. doPost(request, response);
  12. }
  13. @Override
  14. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  15. System.out.println("login doPost被调用...");
  16. //编写servlet(以实现自动填写登录名和密码)
  17. String usernameVal = "";
  18. String pwdVal = "";
  19. //访问servlet时,首先获取浏览器的cookie数组
  20. Cookie[] cookies = request.getCookies();
  21. //判断得到的cookie数组是否存在
  22. if (cookies != null && cookies.length != 0) {//如果存在,且长度不为0
  23. //获取cookie的值
  24. Cookie usernameCookie = CookieUtils.readCookieByName("username", cookies);
  25. Cookie pwdCookie = CookieUtils.readCookieByName("pwd", cookies);
  26. if (usernameCookie != null && pwdCookie != null) {//如果存在指定的cookie
  27. //获取指定的cookie的值
  28. usernameVal = usernameCookie.getValue();
  29. pwdVal = pwdCookie.getValue();
  30. }
  31. }
  32. //绘制html页面
  33. response.setContentType("text/html;charset=utf-8");
  34. PrintWriter writer = response.getWriter();
  35. if (usernameVal != null && pwdVal != null) {
  36. writer.print("<!DOCTYPE html>\n" +
  37. "<html lang=\"en\">\n" +
  38. "<head>\n" +
  39. " <meta charset=\"UTF-8\">\n" +
  40. " <title>登录页面</title>\n" +
  41. "</head>\n" +
  42. "<body>\n" +
  43. "<form action=\"/cs/loginSuccess\" method=\"post\">\n" +
  44. " 用户名:<input type=\"text\" name=\"username\" value=\"" + usernameVal + "\"/><br/>\n" +
  45. " 密码:<input type=\"password\" name=\"pwd\" value=\"" + pwdVal + "\"/><br/>\n" +
  46. " <input type=\"submit\" value=\"登录\"/>\n" +
  47. "</form>\n" +
  48. "</body>\n" +
  49. "</html>");
  50. }
  51. writer.flush();
  52. writer.close();
  53. }
  54. }

LoginSuccess:

  1. package com.li.cookie;
  2. import javax.servlet.*;
  3. import javax.servlet.http.*;
  4. import javax.servlet.annotation.*;
  5. import java.io.IOException;
  6. import java.io.PrintWriter;
  7. /**
  8. * 接收用户输入,判断该用户是否合法,并返回提示信息
  9. */
  10. @WebServlet(urlPatterns = {"/loginSuccess"})
  11. public class LoginSuccess extends HttpServlet {
  12. @Override
  13. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  14. doPost(request, response);
  15. }
  16. @Override
  17. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  18. System.out.println("loginServlet doPost 被调用...");
  19. //1.接收表单用户名和密码
  20. String username = request.getParameter("username");
  21. String pwd = request.getParameter("pwd");
  22. //给浏览器返回提示信息
  23. response.setContentType("text/html;charset=utf-8");
  24. PrintWriter writer = response.getWriter();
  25. //2.判断数据是否合法
  26. if ("olien".equals(username) && "1234".equals(pwd)) {//合法
  27. //将登陆成功的用户名和密码以cookie形式保存到浏览器中
  28. //根据用户名和密码创建cookie
  29. Cookie usernameCookie = new Cookie("username", "olien");
  30. Cookie pwdCookie = new Cookie("pwd", "1234");
  31. //设置cookie生命周期
  32. usernameCookie.setMaxAge(60 * 60 * 24 * 3);//3天
  33. pwdCookie.setMaxAge(60 * 60 * 24 * 3);//3天
  34. //给浏览器返回cookie
  35. response.addCookie(usernameCookie);
  36. response.addCookie(pwdCookie);
  37. //给浏览器返回提示信息
  38. writer.print("<h1>登录OK</h1>");
  39. } else {//不合法
  40. writer.print("<h1>登录失败,请重新登录</h1>");
  41. }
  42. writer.flush();
  43. writer.close();
  44. }
  45. }

redeployTomcat,在浏览器中访问http://localhost:8080/cs/login。 输入正确的用户名密码,成功跳转。


此时,再次访问该页面,可以看到登录页面自动填写登录名:

9.Cookie注意事项和细节

  1. 一个cookie只能标识一种信息,它至少含有一个标识该信息的名称(name)和设置值(value)
  2. 一个web站点可以给一个浏览器发送多个cookie,一个浏览器也可以存储多个web站点提供的cookie
  3. cookie的总数量没有限制,但是每个域名的cookie数量和每个cookie的大小是有限制的(不同的浏览器限制不同),因此cookie不适合存放数据量大的信息
  4. 注意:删除cookie时,path必须一致,否则不会删除
  5. Java Servlet中cookie中文乱码解决。如果cookie存放中文,默认会报错,但可以通过URL编码和解码来解决(尽量不要使用cookie保存中文信息)

例子:解决cookie中文乱码

  1. package com.li.cookie;
  2. import javax.servlet.*;
  3. import javax.servlet.http.*;
  4. import javax.servlet.annotation.*;
  5. import java.io.IOException;
  6. import java.io.PrintWriter;
  7. import java.net.URLEncoder;
  8. @WebServlet(name = "EncoderCookie", urlPatterns = {"/encoderCookie"})
  9. public class EncoderCookie extends HttpServlet {
  10. @Override
  11. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  12. doPost(request, response);
  13. }
  14. @Override
  15. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  16. System.out.println("EncoderCookie doPost被调用...");
  17. //1.创建一个带有中文的cookie
  18. //Cookie company = new Cookie("company", "小葵花公司");
  19. //2.保存到浏览器
  20. /**
  21. * 1.如果直接存放带有中文的cookie,Tomcat服务器会报错:
  22. * Control character in cookie value or attribute.
  23. * 2.解决方法:将中文编码设置成URL编码
  24. * 3.使用工具类 URLEncode
  25. * 4.编码后再保存cookie即可
  26. */
  27. String company = URLEncoder.encode("小葵花公司", "utf-8");
  28. Cookie cookie = new Cookie("company", company);
  29. response.addCookie(cookie);
  30. //3.给浏览器返回提示信息
  31. response.setContentType("text/html;charset=utf-8");
  32. PrintWriter writer = response.getWriter();
  33. writer.print("<h1>设置cookie中文信息成功</h1>");
  34. writer.flush();
  35. writer.close();
  36. }
  37. }
  1. 浏览器访问地址:http://localhost:8080/cs/encoderCookie

  2. 进行抓包:如下,浏览器在保存中文cookie时,以url编码进行保存


  3. 服务器在获取该中文cookie时,也要以url编码形式进行解码,否则得到的cookie的值是url编码。

    ReadCookie2:

    1. package com.li.cookie;
    2. import javax.servlet.*;
    3. import javax.servlet.http.*;
    4. import javax.servlet.annotation.*;
    5. import java.io.IOException;
    6. import java.io.PrintWriter;
    7. import java.net.URLDecoder;
    8. @WebServlet(name = "ReadCookie2", value = "/readCookie2")
    9. public class ReadCookie2 extends HttpServlet {
    10. @Override
    11. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    12. doPost(request, response);
    13. }
    14. @Override
    15. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    16. //读取中文cookie
    17. Cookie[] cookies = request.getCookies();
    18. Cookie companyCookie = CookieUtils.readCookieByName("company", cookies);
    19. String companyVal = companyCookie.getValue();
    20. System.out.println("companyVal= " + companyVal);//url编码
    21. //解码
    22. companyVal = URLDecoder.decode(companyVal, "utf-8");
    23. System.out.println("解码后的companyVal= " + companyVal);//中文
    24. //给浏览器返回提示信息
    25. response.setContentType("text/html;charset=utf-8");
    26. PrintWriter writer = response.getWriter();
    27. writer.print("<h1>读取中文cookie并解码成功</h1>");
    28. writer.flush();
    29. writer.close();
    30. }
    31. }

    浏览器访问该资源,后台输出如下:

day20-web开发会话技术02的更多相关文章

  1. java web Session会话技术(原理图解+功能+与Cookie的区别+基本使用)

    java web Session会话技术(原理图解+功能+与Cookie的区别+基本使用) 这是我关于会话技术的第二篇文章,对 Cookie有不了解的兄弟可以点击下方的Cookie跳转 Cookie链 ...

  2. Java Web之会话技术

    客户端与服务器通信过程中,会产生一些数据.比如,A和B分别登陆了某宝购物网站,A买了一个Android手机,B买了一个iPhone手机,当结账时,web服务器需要分别对用户A和B的信息分别保存.根据J ...

  3. Web开发相关笔记 #02#

    [1] HTML 插入第三方. [2] [3] JavaScript 回调函数 & 模块化 --> 用变量封装数据.方法 --> 类比 Java 中的 package var fe ...

  4. .NET Web开发技术简单整理

    在最初学习一些编程语言.一些编程技术的时候,做的更多的是如何使用该技术,如何更好的使用该技术解决问题,而没有去关注它的相关性.关注它的理论支持,这种学习技术的方式是短平快.其实工作中有时候也是这样,公 ...

  5. Web开发技术发展历史

    Web开发技术发展历史   来自:天码营 原文:http://www.tianmaying.com/tutorial/web-history Web的诞生 提到Web,不得不提一个词就是"互 ...

  6. 转载:.NET Web开发技术简单整理

    在最初学习一些编程语言.一些编程技术的时候,做的更多的是如何使用该技术,如何更好的使用该技术解决问题,而没有去关注它的相关性.关注它的理论支持,这种学习技术的方式是短平快.其实工作中有时候也是这样,公 ...

  7. .NET Web开发技术简单整理 转

    .NET Web开发技术简单整理 原文:http://www.cnblogs.com/SanMaoSpace/p/3157293.html 在最初学习一些编程语言.一些编程技术的时候,做的更多的是如何 ...

  8. 【转载】Web开发技术发展历史-版本1

    原文在这里. Web开发技术发展历史 Web的诞生 提到Web,不得不提一个词就是“互联网”.Web是World Wide Web的简称,中文译为万维网.“万维网”和我们经常说的“互联网”是两个联系极 ...

  9. Web开发技术---简单的登录验证

    制作一个APP或系统最基础的是登录界面,下面通过一个简单的登录注册界面的程序,来熟练掌握Web开发的技术. 一.知识点: 1.在网页界面获取用户的输入信息 2.标签的基本应用 3.用户输入结果的错误提 ...

  10. Web 建站技术中,HTML、HTML5、XHTML、CSS、SQL、JavaScript、PHP、ASP.NET、Web Services 是什么(转)

    Web 建站技术中,HTML.HTML5.XHTML.CSS.SQL.JavaScript.PHP.ASP.NET.Web Services 是什么?修改 建站有很多技术,如 HTML.HTML5.X ...

随机推荐

  1. etcd v3版本生产级集群搭建以及实现一键启动脚本

    本专栏的上一篇文章写了<长篇图解etcd核心应用场景及编码实战>,本文继续.后续计划章节内容如下: <长篇图解etcd核心应用场景及编码实战> <搭建高可用etcd集群& ...

  2. 《网页设计基础——HTML注释与CSS注释》

    网页设计基础--HTML注释与CSS注释       一.HTML注释: 格式: <!-- 在此处书写注释 --> 例如: <html> <head> <ti ...

  3. redis cluster 6.2集群

    redis最新版本:redis-6.2.1.tar.gz 安装的版本是redis-6.0.3 采用的主机: djz-server-001 192.168.2.163 7001,7002,Admin@1 ...

  4. ToroiseGit/GitBash 设置提交信息模板设置

    一.背景:当使用git提交代码时,每次的提交信息固定,却又比较长不好记的时,还需要将模板的地址保存下来,如果能设置一个固定的模板就可以很好的解决这个问题. 提交前的提交信息需要手动输入: 二.Toro ...

  5. PTA 1126 Eulerian Path

    无向连通图,输出每个顶点的度并判断Eulerian.Semi-Eulerian和Non-Eulerian这3种情况,我们直接记录每个点所连接的点,这样直接得到它的度,然后利用深度优先和visit数组来 ...

  6. 汇编指令:lea

    lea指令变种(按大小分类): leaw #2个字节 leal #4个字节 leaq #8个字节 lea的用法: leaq a(b, c, d), %rax 首先lea指令是mov指令的变种,据说,l ...

  7. CAN随机度测试

    在车联网安全测试场景中必不可少的就是对于CAN总线的测试,而CAN总线测试中27服务又是一项必不可少的测试! 当我们进入编程会话请求种子后必定会对种子进行破解,当种子随机度足够安全时就会加大破解难度. ...

  8. 使用开源计算引擎提升Excel格式文件处理效率

    对Excel进行解析\生成\查询\计算等处理是Java下较常见的任务,但Excel的文件格式很复杂,自行编码读写太困难,有了POI\EasyExcel\JExcel等类库就方便多了,其中POI最为出色 ...

  9. Kafka 之producer拦截器(interceptor)

    Kafka 之producer拦截器(interceptor) 一.拦截器原理 Producer拦截器(interceptor)是在Kafka 0.10版本被引入的,主要用于实现clients端的定制 ...

  10. 使用HTML表单收集数据

    1.什么是表单 在项目开发过程中,凡是需要用户填写的信息都需要用到表单. #2.form标签 在HTML中我们使用form标签来定义一个表单.而对于form标签来说有两个最重要的属性:action和m ...