• 18.客户端会话技术Cookie


    目录

    一、会话技术(Cookie和Session)

    二、客户端会话技术Cookie

    1.Cookie的实现原理

    2.Cookie使用步骤

    3.Cookie的特点

    3.1Cookie可以创建几个对象?

    3.2Cookie的存活时间?

    3.3Cookie存取中文?

    3.4Cookie的共享问题

    4.Cookie的作用

    5.使用Cookie实现记录上一次登录的访问时间


    一、会话技术(Cookie和Session)

    会话:一次会话中包含多次请求和响应,

    一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止

    功能:在一次会话的范围内的多次请求建立连接,共享数据

    客户端会话技术Cookie和服务器端会话技术Session

    二、客户端会话技术Cookie

    客户端会话技术,将数据保存到客户端

    1.Cookie的实现原理

    客户端请求服务器后,如果服务器需要记录用户状态,服务器会在响应信息中包含一个Set-Cookie的响应头,客户端会根据这个响应头存储Cookie信息。再次请求服务器时,客户端会在请求信息中包含一个Cookie请求头,而服务器会根据这个请求头进行用户身份、状态等较验。

    2.Cookie使用步骤

    先创建Cookie对象,绑定数据

    new Cookie(String name, String value)

    发送Cookie对象

    resp.addCookie(Cookie cookie)

    获取Cookie对象,拿到数据

    Cookie[] cookie =  req.getCookie()

    1. @WebServlet("/only-set-cookie")
    2. public class OnlySetCookieServlet extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    6. // 创建Cookie对象
    7. Cookie cookie1 = new Cookie("first-name", "first-pwd");
    8. // 发送Cookie对象
    9. resp.addCookie(cookie1);
    10. // 创建Cookie对象
    11. Cookie cookie2 = new Cookie("second-name", "second-pwd");
    12. // 发送Cookie对象
    13. resp.addCookie(cookie2);
    14. }
    15. }
    16. }
    1. @WebServlet("/only-get-cookie")
    2. public class OnlyGetCookieServlet extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. // 获取Cookie对象
    6. Cookie[] cookies = req.getCookies();
    7. if(cookies != null){
    8. for (Cookie cookie : cookies) {
    9. System.out.println(cookie.getName() + ":" + cookie.getValue());
    10. }
    11. }
    12. }
    13. }

    先在浏览器访问/only-set-cookie,再访问/only-get-cookie

    当访问/only-set-cookie时,由于是第一次访问,请求头是不带参数的,但是响应头中有set-Cookie

     

    当访问/only-get-cookie时请求头中有Cookie

    3.Cookie的特点

    (1)Cookie存储数据在客户端浏览器

    (2)浏览器对于单个Cookie的大小有一定的限制(4kb),对于同一个域名下的总Cookie数量有限制(20个)

    (3)一次可以创建多个Cookie对象,使用response多次调用addCookie方法发送Cookie即可

    3.1Cookie可以创建几个对象?

    一次可以创建多个Cookie对象,使用response多次调用addCookie方法发送Cookie即可

    3.2Cookie的存活时间?

    默认情况下,当浏览器关闭后,Cookie数据被销毁。但是如果想要持久化存储可以调用setMaxAge(int second)方法设置时间,时间到后,Cookie文件会自动失效。

    • maxAge设置正数:将Cookie数据写入硬盘文件中,设置Cookie的存活时间
    • maxAge设置正数:表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。maxAge为负数的Cookie,为临时性Cookie,不会被持久化,不会被写到Cookie文件中。Cookie信息保存在浏览器内存中,因此关闭浏览器该Cookie就消失了。Cookie默认的maxAge值为-1
    • maxAge设置为0:表示删除该Cookie。Cookie机制没有提供删除Cookie的方法,因此通过设置该Cookie即时失效实现删除Cookie的效果。失效的Cookie会被浏览器从Cookie文件或者内存中删除

    3.3Cookie存取中文?

    有时候使用Cookie存取中文会出现乱码的问题,这时候在存取Cookie时需要使用URL编码进行一个编码和解码

    编码:String value = URLEncoder.encode("张三", "utf-8");

    解码:URLDecoder.decode(cookie.getValue(), "UTF-8");

    1. @WebServlet("/demo")
    2. public class Demo extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. // 创建Cookie对象
    6. String value = URLEncoder.encode("张三", "utf-8");
    7. Cookie cookie1 = new Cookie("name", value);
    8. // 发送Cookie对象
    9. resp.addCookie(cookie1);
    10. }
    11. }
    1. @WebServlet("/Get")
    2. public class Get extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. // 获取Cookie对象
    6. Cookie[] cookies = req.getCookies();
    7. for (Cookie cookie : cookies) {
    8. System.out.println(cookie.getName() + ":" + URLDecoder.decode(cookie.getValue(), "UTF-8"));
    9. }
    10. }
    11. }

    在请求头和响应头中看到的是编码之后的内容 

    在IDEA中打印出来的信息

    3.4Cookie的共享问题

    当使用同一个tomcat启动两个Web项目时,怎么让两个项目获取到的Cookie进行共享

    demo1下的Set和Get,demo1下的Cookie是first-name first-pwd

    1. @WebServlet("/Set")
    2. public class Set extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. // 创建Cookie对象
    6. Cookie cookie = new Cookie("first-name", "first-pwd");
    7. // 发送Cookie对象
    8. resp.addCookie(cookie);
    9. }
    10. }
    1. @WebServlet("/Get")
    2. public class Get extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. // 获取Cookie对象
    6. Cookie[] cookies = req.getCookies();
    7. for (Cookie cookie : cookies) {
    8. System.out.println(cookie.getName() + " " +cookie.getValue());
    9. }
    10. }
    11. }

    demo2下的Set和Get ,demo2下的Cookie是Second-name Second-pwd

    1. @WebServlet("/set")
    2. public class Set extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. // 创建Cookie对象
    6. Cookie cookie = new Cookie("second-name", "second-pwd");
    7. // 发送Cookie对象
    8. resp.addCookie(cookie);
    9. }
    10. }
    1. @WebServlet("/get")
    2. public class Get extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. // 获取Cookie对象
    6. Cookie[] cookies = req.getCookies();
    7. for (Cookie cookie : cookies) {
    8. System.out.println(cookie.getName() + " " + cookie.getValue());
    9. }
    10. }
    11. }

    先访问/demo1/Set和 /demo1/Get

    先访问/demo2/set和 /demo2/get 

    说明两个项目中获取到的Cookie是不一样的,如果想从demo2中获取到demo1中的Cookie,可以使用cookie.setPath("/");

    cookie.setPath("/");

    demo1中的Set类

    1. @WebServlet("/Set")
    2. public class Set extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. // 创建Cookie对象
    6. Cookie cookie = new Cookie("first-name", "first-pwd");
    7. // 发送Cookie对象
    8. cookie.setPath("/");
    9. resp.addCookie(cookie);
    10. }
    11. }

    先从demo1中获取到Cookie 

     

    再从demo2中获取到Cookie,这样就可以实现Cookie的共享  

     

    如果是不同的两个tomcat,怎么让两个项目获取到的Cookie进行共享,使用cookie.setDomain()方法,这个参数必须以“.”开始。  输入url访问的时候,必须输入域名才能解析。如果使用  cookie.setDomain(".new.com");,在另外一个电脑上输入http://home.new.com:8080/就可以获得Cookie,如果输入http://localhost:8080/就不能获得Cookie

      cookie.setDomain(".new.com");

    4.Cookie的作用

    (1)Cookie一般用于存储少量的不太敏感的数据

    (2)可以在不登陆的情况下,完成服务器对客户端的身份识别

    5.使用Cookie实现记录上一次登录的访问时间

    1.访问一个Servlet,如果是第一次访问,提示:欢迎您首次访问

    2.如果不是第一次访问,提示:欢迎回来,上次访问时间是:显示字符串

    在服务器中的Servlet判断是否存在一个lastTime的Cookie

    第一次访问-----提示:欢迎您首次访问,写回Cookie

    不是第一次访问-----提示:欢迎回来,写回Cookie

    1. package cn;
    2. import javax.servlet.ServletException;
    3. import javax.servlet.annotation.WebServlet;
    4. import javax.servlet.http.Cookie;
    5. import javax.servlet.http.HttpServlet;
    6. import javax.servlet.http.HttpServletRequest;
    7. import javax.servlet.http.HttpServletResponse;
    8. import java.io.IOException;
    9. import java.net.URLDecoder;
    10. import java.net.URLEncoder;
    11. import java.text.SimpleDateFormat;
    12. import java.util.Date;
    13. @WebServlet("/lastTimeCookie")
    14. public class LastTimeCookie extends HttpServlet {
    15. @Override
    16. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    17. resp.setContentType("text/html;charset=utf-8");
    18. // 1.先获取所有的Cookie
    19. Cookie[] cookies = req.getCookies();
    20. if(cookies == null || cookies.length == 0){
    21. // 第一次访问
    22. Date date = new Date();
    23. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    24. String time = sdf.format(date);
    25. // 因为time中间有个空格,要进行URL编码解码
    26. time = URLEncoder.encode(time, "utf-8");
    27. Cookie cookie = new Cookie("lastTime",time);
    28. // 设置Cookie的存活时间,一个月
    29. cookie.setMaxAge(60 *60 *24 *30);
    30. resp.addCookie(cookie);
    31. resp.getWriter().write("欢迎您首次访问");
    32. }
    33. if(cookies != null){
    34. for(Cookie cookie: cookies){
    35. String name = cookie.getName();
    36. if(name.equals("lastTime")){
    37. // 获取当前时间,重新设置Cookie值
    38. Date date = new Date();
    39. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    40. String time = sdf.format(date);
    41. // 因为time中间有个空格,要进行URL编码解码
    42. time = URLEncoder.encode(time, "utf-8");
    43. cookie.setValue(time);
    44. // 设置Cookie的存活时间,一个月
    45. cookie.setMaxAge(60 *60 *24 *30);
    46. resp.addCookie(cookie);
    47. String value = URLDecoder.decode(cookie.getValue(), "utf-8");
    48. resp.getWriter().write("欢迎回来,上次访问时间是" + value);
    49. break;
    50. }
    51. }
    52. }
    53. }
    54. }

     首次访问

    第二次访问 

     

     

  • 相关阅读:
    leetcode 518. 零钱兑换 II、377. 组合总和 Ⅳ
    Java实现图片和Base64之间的相互转化
    记录在vue开发上遇到的一些问题
    【LeetCode热题100】【图论】腐烂的橘子
    python中值滤波
    [Java安全]—Tomcat Servlet内存马
    号称超级增程电动,领克07EM-P带来技术变革?
    Web前端:React对比Vue,哪一个最适合开发人员?
    代码随想录算法训练营第23期day3| 203.移除链表元素 ,707.设计链表,206.反转链表
    nrf9160做主控连接阿里云(mqtt_simple例程)——附MQTT协议浅解
  • 原文地址:https://blog.csdn.net/qq_46235384/article/details/126054670