• Cookie和Session详解以及结合生成登录效果


    目录

    引言 

    1.Cookie中的数据从哪来数据长啥样?

    2.Cookie有什么作用?

    3.cookie与session的工作关联?

    4.Cookie到哪去? 

    5.Cookie如何存? 

    6.Session 

     7.Cookie与Session的关联与区别

    8.通过代码理解 

    8.1 相关代码

    8.2 观察现象

    8.3 总结 

    9.Cookie结合Session 实现登录效果

    1.前端代码(简易版界面)

    2.后端 

    3.现象

     4.小结

    get和post的区别在这里有介绍: 


    引言 

    Cookie是浏览器提供的持久化存储数据的机制

    1.Cookie中的数据从哪来数据长啥样?

    cookie 是从服务器返回给浏览器的;是由程序员代码自定义的键值对结构数据。要在浏览器cookie中保存哪些数据,通过http响应的Set-Cookie字段把键值对写回去

    2.Cookie有什么作用?

     Cookie在浏览器中存储临时数据

    最典型的应用:存储“身份标识.

    3.cookie与session的工作关联?

    此处的身份标识(sessionId)就涉及到cookie和session的梦幻联动。

    cookie是浏览器存储数据,session是服务器存储数据(存储用户的详细信息,同时给用户分配一个sessionId),此时服务器就把sessionId返回给浏览器,后续再访问浏览器中的页面时就会在请求上自动带上我们的sessionId,进一步服务器就知道哪个用户在操作了。

    4.Cookie到哪去? 

    Cookie中的内容会在下次访问该网站的时候自动带到http请求中。

    5.Cookie如何存? 

    cookie存储在浏览器所在的硬盘(往往会存在超时时间)中,浏览器按照不同的域名分别存储cookie,域名和域名之间的cookie不同相互干扰。

    cookie在浏览器存储的目的是后续访问服务器的时候,通过请求的header将cookie发送给服务器

    作用:因为服务器是同时服务多个客户端的,客户端需要借助cookie来告诉服务器当前提供的服务到哪个环节了,服务器也可以通过cookie识别该客户端

    6.Session 

    上述服务器生成了一些键值对结构数据,就是session(会话)

    生成的唯一的身份序号叫做sessionid,也就是key,value就是记录的身份信息


    具体流程:

    用户登陆时,服务器在session中添加一个key-value记录,并且将key通过setCookie返回给客户端,客户端存储了cookie信息
    客户端后续再发请求到服务器的时候,会通过http的header携带cookie信息
    服务器收到请求之后,根据根据请求中的sessionid/token 在s ession 信息中获取到对应的用户信息 ,再决定后续的操作.
     

     7.Cookie与Session的关联与区别

    Cookie和Session也是常用的跟踪用户身份和状态管理的机制。它们之间的关联与区别如下:

    关联:

    • 在使用Session时,通常会在客户端保存一个名为JSESSIONID的Cookie,用于标识用户会话。
    • 服务器根据JSESSIONID从存储Session的位置(如内存或数据库)中获取对应的数据。

    区别:

    • 存储位置:在Java中,HttpSession接口提供了对Session的访问和管理,Session对象默认存储在服务器端,而Cookie存储在客户端。
    • 数据容量:Cookie每个域名下的浏览器对数量和大小都有限制,而Session相对可以存储更多的数据。
    • 生命周期:Cookie可以设置过期时间,可以是临时的或长期有效的;而Session一般在会话结束后自动销毁,也可以手动设置过期时间。
    • 安全性:由于存储在客户端,Cookie存在被篡改和盗用的风险,可以通过设置属性增加安全性;而Session存储在服务器端,相对更安全。
    • 跨域支持:Cookie默认情况下只能在同一域内共享,可以通过设置domain属性实现跨域共享;而Session不受域的限制,可以在不同域之间共享。

    在Java Web开发中,通常会使用Servlet API提供的HttpSession对象来管理Session。在登录认证成功后,服务器会创建一个唯一的JSESSIONID,并将相关的用户信息存储在HttpSession对象中,然后将JSESSIONID以Cookie的方式发送给客户端保存。客户端在后续的请求中会携带该Cookie,服务器通过解析Cookie中的JSESSIONID来获取对应的HttpSession对象,从而实现用户身份的认证和状态的保持。


    8.通过代码理解 

    8.1 相关代码

    1. import javax.servlet.ServletException;
    2. import javax.servlet.annotation.WebServlet;
    3. import javax.servlet.http.Cookie;
    4. import javax.servlet.http.HttpServlet;
    5. import javax.servlet.http.HttpServletRequest;
    6. import javax.servlet.http.HttpServletResponse;
    7. import java.io.IOException;
    8. @WebServlet("/getcookie")
    9. public class GetCookieServlet extends HttpServlet {
    10. @Override
    11. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    12. //获取到这次请求的cookie
    13. Cookie[] cookies=req.getCookies();
    14. if(cookies!=null){
    15. for(Cookie cookie:cookies){
    16. System.out.println(cookie.getName()+" "+cookie.getValue());
    17. }
    18. }else{
    19. System.out.println( "请求中没有cookie");
    20. }
    21. //这里的if else 判断是在网页访问过程,500提示码提示的
    22. resp.getWriter().write("ok");
    23. }
    24. }
    1. import javax.servlet.ServletException;
    2. import javax.servlet.annotation.WebServlet;
    3. import javax.servlet.http.Cookie;
    4. import javax.servlet.http.HttpServlet;
    5. import javax.servlet.http.HttpServletRequest;
    6. import javax.servlet.http.HttpServletResponse;
    7. import java.io.IOException;
    8. /**
    9. * Created with IntelliJ IDEA.
    10. * Description:
    11. * User: 86180
    12. * Date: 2023-10-04
    13. * Time: 23:20
    14. */
    15. @WebServlet("/setcookie")
    16. public class SetCookieServlet extends HttpServlet {
    17. @Override
    18. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    19. //想通过这个方法把自定义的数据返回到浏览器
    20. Cookie cookie=new Cookie("data","2023-09-23");
    21. Cookie cookie1=new Cookie("time","09:48");
    22. resp.addCookie(cookie);
    23. resp.addCookie(cookie1);
    24. resp.getWriter().write("setCookie ok");
    25. }
    26. }

     在pom.xml中从maven仓库https://mvnrepository.com/?__cf_chl_rt_tk=ptb7mN.OmXB2Pdf.tn5HNQSGzovAURAXJ95hEAo9vIA-1696475447-0-gaNycGzNDTs导入servlet和Jackson的对应依赖

    8.2 观察现象

    通过fiddler抓包就可以看出访问setcookie请求的时候,代码中就会构造cookie放在响应中,

    进一步就返回到我们的浏览器中,后续再发请求的时候,我们的cookie就会在请求中

    这时2,我们通过getcookie去获取,就可以再idea服务器中看到相应的cookie

    8.3 总结 

    cookie从服务器来,服务器调用相应的api,就可以给api添加setcookie字段,setcookie字段里面就是我们自定义的键值对,浏览器收到这些键值对,就会把这些键值对保存在浏览器本地,后续再给网站发送请求,就可以把cookie带到header里面 

    9.Cookie结合Session 实现登录效果

     每个用户都应该有自己的session,session在服务器中存在很多份,每个服务器同时会有很多session,所以服务器会使用map来组织多个session,就像是一个Map

    1.前端代码(简易版界面)

    1. "en">
    2. "UTF-8">
    3. "viewport" content="width=device-width, initial-scale=1.0">
    4. 登录
    5. "login"method="post">
    6. "text" name="username">
    7. "password" name="password">
    8. "submit" value="登录">

     在idea重启服务器后

    2.后端 

    loginServlet(整体登录背后的逻辑成功登录后跳转)和IndexServlet(通过这个网页生成一个servlet)

    1. /**getSession背后做的事情:
    2. *💡1.先读取请求中的cookie,看cookie中是否有JSESSIONID属性以及值是啥
    3. * 如果没有就认为需要创建新的会话;
    4. * 如果有,就拿着这个id去查询看看当前的session是否存在;
    5. * 要是session存在,就直接返回该session;
    6. * 要是session不存在就创建新的会话;
    7. *💡2.当前确实需要创建会话就会出安检处一个session对象,同时生成一个唯一的JSESSIONID.
    8. * 以JSESSIONID为key,Session对象为value,把这个键值对给插入到服务器的哈希表中。
    9. *💡3.刚才生成的JSESSIONID又会通过addCookie方法加入到 响应 中,
    10. * 此事响应就会带有Set-Cookie字段,这里的值就是JSESSIONID=****,
    11. * 通过响应,就把JsessionID返回到浏览器
    12. *
    13. * **/
    14. import javax.servlet.ServletException;
    15. import javax.servlet.annotation.WebServlet;
    16. import javax.servlet.http.HttpServlet;
    17. import javax.servlet.http.HttpServletRequest;
    18. import javax.servlet.http.HttpServletResponse;
    19. import javax.servlet.http.HttpSession;
    20. import java.io.IOException;
    21. @WebServlet("/login")
    22. public class loginServlet extends HttpServlet {
    23. @Override
    24. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    25. //1.先使用getParameter获取到username,password的值
    26. String username = req.getParameter("username");
    27. String password = req.getParameter("password");
    28. //验证信息是否正确
    29. //正常用数据库保存,这里写死
    30. //2.验证合法:zhangsan 123456
    31. if(!username.equals("zhangsan")){
    32. //失败
    33. //重定向=>登录页
    34. System.out.println("用户名错误");
    35. resp.sendRedirect("login.html");
    36. return;
    37. /**如果你想在登陆页面也显示出内容,就是如果错误就在页面显示用户名错误;
    38. * 就getWriter.write()
    39. * resp.setContentType("text/html;charset = utf8");
    40. * resp.getWriter().write("用户名错误");
    41. * 这边未注释的代码是显示到服务器端,在我们idea上就可以看见
    42. * */
    43. }
    44. if(!password.equals("123456")){
    45. //失败
    46. System.out.println("密码错误");
    47. resp.sendRedirect("login.html");
    48. return;
    49. }
    50. //成功
    51. //3.创建会话
    52. HttpSession session = req.getSession(true);
    53. //getSission(true);是拿着sessionId查一下哈希表,
    54. //如果sessionId不存在.或者没查到,就创建新会话插入到哈希表
    55. // 查到了就返回查到的结果
    56. //如何创建?
    57. //1.构造HttpSession对象
    58. //2.构造唯一的sessionId
    59. //3.把这个键值对插入哈希表
    60. //4.把sessionId设置到响应报文Set-Cookie字段
    61. //将用户信息保存到session对象中,保存一些自定义数据
    62. session.setAttribute("username",username);
    63. session.setAttribute("time",System.currentTimeMillis());
    64. //4.重定向到主页
    65. resp.sendRedirect("index");
    66. }
    67. }写死
    68. //合法:zhangsan 12345
    69. if(!username.equals("zhangsan")){
    70. //失败
    71. //重定向=>登录页
    72. System.out.println("用户名错误");
    73. resp.sendRedirect("login.html");
    74. return;
    75. /**如果你想在登陆页面也显示出内容,就是如果错误就在页面显示用户名错误;
    76. * 就getWriter.write()
    77. * resp.setContentType("text/html;charset = utf8");
    78. * resp.getWriter().write("用户名错误");
    79. * 这边未注释的代码是显示到服务器端,在我们idea上就可以看见
    80. * */
    81. }
    82. if(!password.equals("123456")){
    83. //失败
    84. System.out.println("密码错误");
    85. resp.sendRedirect("login.html");
    86. return;
    87. }
    88. //成功
    89. //创建会话
    90. HttpSession session = req.getSession(true);
    91. //getSission(true);是拿着sessionId查一下哈希表,
    92. //如果sessionId不存在.或者没查到,就创建新会话插入到哈希表
    93. // 查到了就返回查到的结果
    94. //如何创建?
    95. //1.构造HttpSession对象
    96. //2.构造唯一的sessionId
    97. //3.把这个键值对插入哈希表
    98. //4.把sessionId设置到响应报文Set-Cookie字段
    99. //将用户信息保存到session对象中,保存一些自定义数据
    100. session.setAttribute("username",username);
    101. session.setAttribute("time",System.currentTimeMillis());
    102. //重定向到主页
    103. resp.sendRedirect("index");
    104. }
    105. }
    1. /**
    2. * Created with IntelliJ IDEA.
    3. * Description:
    4. * User: 86180
    5. * Date: 2023-10-05
    6. * Time: 18:05
    7. */
    8. import javax.servlet.ServletException;
    9. import javax.servlet.annotation.WebServlet;
    10. import javax.servlet.http.HttpServlet;
    11. import javax.servlet.http.HttpServletRequest;
    12. import javax.servlet.http.HttpServletResponse;
    13. import javax.servlet.http.HttpSession;
    14. import java.io.IOException;
    15. //通过这个网页生成一个servlet
    16. @WebServlet("/index")
    17. public class IndexServlet extends HttpServlet {
    18. @Override
    19. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    20. //1.先判定用户登陆状态
    21. //若没登陆.先登录
    22. //若登录,根据绘画用户名信息,显示到页面上
    23. HttpSession session = req.getSession(false);
    24. //不会触发会话创建
    25. if(session==null){
    26. System.out.println("用户未登录");
    27. resp.sendRedirect("login.html");
    28. return;
    29. }
    30. //2.登陆成功了取出之前的attribute
    31. String username = (String) session.getAttribute("username");
    32. Long time=(Long)session.getAttribute("time");
    33. System.out.println("username"+username+"time"+time);
    34. //执行到这里,session和post中的是一个对象
    35. //根据同一个sessionid对应到的对象
    36. //3.根据这样的内容构造出一个页面
    37. resp.setContentType("text/html;charset = utf8");
    38. resp.getWriter().write("欢迎您:" + username+"!上次登录时间"+time);
    39. }
    40. }

    3.现象

    登陆成功后效果,登陆失败会在服务器端显示,如果想在页面也显示出来可以在loginServlet中对应位置代码中加上

    resp.setContentType("text/html;charset = utf8");
    resp.getWriter().write("*****");

    通过 session.setAttribute("username",username);也将用户名保存了进去。

     4.小结

     当前这个程序,就涉及到三个部分进行联动~~

    1.登陆页面(静态的 html ,使用 form 构造 http 请求)

    2. LoginServlet ( doPost 处理登陆的逻辑流程1234)

    3. IndexServlet ( doGet 处理主页的生成)

    get和post的区别在这里有介绍: 

    【http协议与tomcat - CSDN App】http://t.csdnimg.cn/s9K09

  • 相关阅读:
    java面试题_消息中间件--RabbitMQ(20题)
    【git】gitlab常用命令
    Java常量池理解
    L55.linux命令每日一练 -- 第八章 Linux磁盘与文件系统管理命令 -- mkswap和swapon
    【JVM】G1垃圾收集器知多少
    BST基本性质,LeetCode 235. 二叉搜索树的最近公共祖先
    Protobuf生成文件报错
    前端实习最终章
    “女生最适合软件测试、没有之一”都是骗子,我们都上当受骗了
    使用python读取csv文件中的数据
  • 原文地址:https://blog.csdn.net/m0_74106420/article/details/133556655