• JavaWeb--Cookie与Session


    前言

    • Java Web 其实就是一个技术的总和,把Web看成一个容器而已主要使用JavaEE技术来实现.在加上各种中间件。
    • 整个javaWeb阶段的内容通过实际的案例贯穿学习, 所涉及到的技术知识点会在案例中根据不同的需求引入。
    • 首先了解javaWeb的整个技术体系,掌握常用的技术知识点。

    我会将JavaWeb分为8篇左右的文章来记录自己的学习过程,也方便大家逐级递增难度的学习,如有错误或遗漏欢迎大家指出。

    注:本篇文章承接上一篇JavaWeb文章JavaWeb--Servlet详解
    下面我们进入正题!

    7、Cookie、Session

    7.1、会话

    会话:用户打开了一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话

    有状态会话:记录了一些信息

    大家在浏览网站的过程中有没有思考过这样一个问题,一个网站怎么证明客户访问过呢?

    客户端 服务端

    1.服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了 : cookie

    2.服务器登记客户已经来过了,下次访问的时候直接匹配登记过的客户 ; session

    3.大家可以先看一下这张图,下面对Cookie与Session的讲解就是围绕这张图展开的,最后会对这张图进行详细的讲解

    7.2、保存会话的两种技术

    7.2.1、cookie

    • 客户端技术(响应,请求)
    • cookie一般是以键值对的形式进行表示的(key-value)
    • 我们登录过一个网站,当我们再次打开就不需要再次登录了

    7.2.2、session

    • 服务器技术(保存用户的会话信息,可以把信息或者数据放在session中)
    • 每个客户端都有自己的一个Session会话
    • Session会话中,我们经常用来保存用户登录之后的信息

    大部分的网站:网站登录之后,下次就不用再登录了,第二次访问直接就可以登录进去

    7.3、Cookie

    1.cookie中常用属性的解释

    • Name:这个是cookie的名字
    • Value:这个是cooke的值
    • path:这个定义了Web站点上可以访问该Cookie的目录
    • Expircs:这个值表示cookie的过期时间,也就是有效值,cookic在这个值之前都有效。
    • size:这个表示cookic的大小

    2.Cookie的Http传输

    Cookie的Http传输 我们会在接下来的例子中进行抓包展示

    3.Cookie的生命周期

    cookie有2种存储方式,一种是会话性,一种是持久性

    • 会话性:如果cookie为会话性,那么cookie仅会保存在客户端的内存中,当我们关闭客服端时cookie也就失效了
    • 持久性:如果cookie为持久性,那么cookie会保存在用户的硬盘中,直至生存期结束或者用户主动将其销毁。

    cookie我们是可以进行设置的,我们可以人为设置cookie的有效时间,什么时候创建,什么时候销毀。

    4.cookie 使用的常见方法

    java中Cookie对象的方法进行讲解

    • new Cookie(String name, String value):创建一个Cookie对象,必须传入cookie的名字和cookic的值
    • setValue():得到cookie保存的值
    • getName():获取cookie的名字
    • setMaxAge(int expiry):设置cookie的有效期,默认为-1。这个如果设置负数,表示客服端关闭,cookie就会删除。0表示马上删除。正数表示有效时间,单位是秒
    • setPath(String uri):设置cookie的作用域

    HttpServletRequest和Http ServletResponse对Cookie进行操作的常见方法

    • response.addCookie(Cookie cookie):将cookie给客户端进行保存
    • resquest.getCookies0:得到客服端传过来的所有cookie对象

    这张图是客户端携带Cookie访问服务器的流程图

    7.3.1、用代码实现保存用户上一次访问的时间

    1. 从请求中拿到cookie信息

    2. 服务端响应给客户端cookie

    //保存用户上一次访问的时间
    
    public class CookieDemon01 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //服务器告诉你你来的时间,把这个时间封装为一个信件,你下次来,我就知道你来了
    
    
            //解决中文乱码,这里解决乱码需要根据实际情况自己进行调试
            req.setCharacterEncoding("gbk");
            resp.setCharacterEncoding("gbk");
    
            PrintWriter out = resp.getWriter();
    
            //cookie,服务器端从客户端获取
            Cookie[] cookies = req.getCookies();//返回数组说明cookie可能存在多个
    
            //判断cookie是否存在
            if (cookies != null) {
            //如果存在怎么办
                out.write("您上一次访问的时间是:");
    
                for (int i = 0; i < cookies.length; i++) {
                    Cookie cookie = cookies[i];
                    //获取cookie的名字
    
                   if( cookie.getName().equals("LastLogTime")){
                       //获取cookie的值
    
                       long lastLogTime = Long.parseLong(cookie.getValue());
                       Date date = new Date(lastLogTime);
                       out.write(date.toLocaleString());
    
                   }
                }
                
            }else {
                out.write("这是您第一次访问本站");
            }
            
            //服务器给客户端响应一个cookie
    
            Cookie cookie = new Cookie("LastLogTime", System.currentTimeMillis()+"");
            //设置cookie有效期为一天(浏览器关闭cookie还存在一天)
            cookie.setMaxAge(24*60*60);
    
            resp.addCookie(cookie);
    
            
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
    折叠

    3.注册Servlet

     <servlet>
        <servlet-name>CookieDemo01servlet-name>
        <servlet-class>com.qid.servlet.CookieDemon01servlet-class>
      servlet>
    
      <servlet-mapping>
        <servlet-name>CookieDemo01servlet-name>
        <url-pattern>/c1url-pattern>
    

    4.测试访问

    第一次访问

    第二次访问

    接下来我们抓包查看Cookie的Http传输

    注:cookie一般会保存在本地的用户目录下AppData ,浏览器只会携带在当前请求的URL中包含了改cookie中path值的cookie

    了解一下:
    一个网站cookie是否存在上限?

    • 一个cookie只能保存一个信息
    • 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie
    • cookie大小上限为4kb
    • 300个cookie大约为浏览器上限

    7.3.2、删除cookie:

    • 不设置有效期,关闭浏览器,自动失效

    • 设置有效期为0

      public class CookieDemon02 extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         
              //创建一个cookie.名字必须和要删除的名字一致
              Cookie cookie = new Cookie("LastLogTime", System.currentTimeMillis()+"");
              //有限期为0
              cookie.setMaxAge(0);
      
              resp.addCookie(cookie);
              
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req, resp);
          }
      }
      

    7.3.3、中文传输数据乱码问题

    这里再用上面记录访问时间的例子说一下传输中文数据的问题:

    如果一直中文传输数据乱码,可以尝试以下代码:

    编码解码

    //编码
    Cookie cookie = new Cookie("name", URLEncoder.encode("张三","utf-8"));
     //解码
     out.write( URLDecoder.decode(cookie.getValue(),"utf-8"));
    

    整体代码:

    
    //中文数据传递
    
    public class CookieDemon03 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
            //解决中文乱码
            req.setCharacterEncoding("utf-16");
            resp.setCharacterEncoding("utf-16");
            //cookie,服务器端从客户端获取
            Cookie[] cookies = req.getCookies();//返回数组说明cookie可能存在多个
    
    
            PrintWriter out = resp.getWriter();
    
            //判断cookie是否存在
            if (cookies != null) {
                //如果存在怎么办
                out.write("您的名字是:");
    
                for (int i = 0; i < cookies.length; i++) {
                    Cookie cookie = cookies[i];
                    //获取cookie的名字
    
                    if( cookie.getName().equals("name")){
                        //获取cookie的值
                        System.out.println(cookie.getValue());
                       //解码
                        out.write( URLDecoder.decode(cookie.getValue(),"utf-8"));
    
                    }
                }
    
            }else {
                out.write("这是您第一次访问本站");
            }
            //编码
            Cookie cookie = new Cookie("name", URLEncoder.encode("张三","utf-8"));
            resp.addCookie(cookie);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
    折叠

    注册servlet后测试结果

    7.4、Session(重点)

    7.4.1、Session的概念

    1.什么是session

    • 服务器会给每一个用户(浏览器)创建一个Session
    • 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
    • 用户登录之后,整个网站它都可以访问--->保存用户的信息

    2.Session的常用方法

    • request.getSession():创建(第一次调用)或获取Session会话对象
    • isNew():判断当前Session会话是否是新创建出来的
    • getId():得到Session的会话ID
    • setAttribute():往Session中保存数据
    • getAttribute():获取Session域中的数据

    3.Session的生命周期

    • 手动注销:session.invalidate();

    • 自动注销:在web.xml 中配置

    
      <session-config>
    
        <session-timeout>15session-timeout>
      session-config>
    

    4.session应用:

    • 保存一个登录用户的信息
    • 购物车信息
    • 在整个网站中经常会使用的数据,我们将它保存在Session中

    下面这张图是服务器登记session,客户端用sessionID访问的流程图

    7.4.2、具体使用session

    1.保存数据:

    • Person.java
    • SessionDemon01(设置信息)
    • SessionDemon02(得到信息)
    public class Person {
    
        private String name;
        private int age;
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    
        public Person() {
        }
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }
    
    折叠
    public class SessionDemon01 extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
            //解决乱码问题
            req.setCharacterEncoding("gbk");
            resp.setCharacterEncoding("gbk");
            resp.setContentType("text/html;charset = gbk");
    
            //得到Session
    
            HttpSession session = req.getSession();
    
            //给Session中存东西
            session.setAttribute("name",new Person("李四",18));
    
    
            //获取session的id
            String sessionId = session.getId();
    
            //判断session是不是新创建的
            if(session.isNew()){
                resp.getWriter().write("session创建成功,id:"+sessionId);
            }else {
                resp.getWriter().write("session已经在服务器中存在了,id:"+sessionId);
            }
    
    
            //Session创建的时候做了什么事情
    //        Cookie cookie = new Cookie("JSESSIONID",sessionId);
    //        resp.addCookie(cookie);
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
    折叠
    public class SessionDemon02 extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
            //解决乱码问题
            req.setCharacterEncoding("gbk");
            resp.setCharacterEncoding("gbk");
            resp.setContentType("text/html;charset = gbk");
    
            //得到Session
    
            HttpSession session = req.getSession();
            Person person = (Person) session.getAttribute("name");
            resp.getWriter().write(person.toString());
            System.out.println(person.toString());
    
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

    注册Servlet测试访问
    (1)访问设置信息s1

    (2)访问得到信息s2

    2.会话过期

    • 手动

      public class SessionDemon03 extends HttpServlet {
      
              //注销,移除
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      
              HttpSession session = req.getSession();
              session.removeAttribute("name");
              //手动注销session
              session.invalidate();//一旦注销会重新产生一个sessionId
              
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req, resp);
          }
      }
      
    • 自动

      
        <session-config>
      
          <session-timeout>15session-timeout>
        session-config>
      

    最后我们再回到刚开始的问题,一个网站怎么证明你来过呢?

    思考 : Session和Cookie的区别

    ①cookie可以存储在浏览器或者本地,Session只能存在服务器
    ②session能够存储任意的java对象,cookie 只能存储String 类型的对象
    ③Session比tCookie更具有安全性(Cookie有安全隐患,通过拦截或本地文件找得到你的cookie后可以进行攻击)
    ④Session占用服务器性能,Session过多,增加服务器压力
    ⑤单个Cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个Cookie,Session是没有大小限制和服务器的

    到这里关于Cookie与Session的知识就结束啦≧ω≦,希望对大家有所帮助!

    大家觉得文章还可以的话可以点个推荐支持博主啊 (u‿ฺu✿ฺ)


    __EOF__

  • 本文作者: 鹤鸣呦呦、、
  • 本文链接: https://www.cnblogs.com/qjds/p/16545106.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    Redis面试---缓存问题
    dataHost标签详解
    java:SpringBoot入门
    Word制作生成html模板替换动态值为占位符使用Java转为pdf文件
    iOS添加Mapbox地图库
    嵌入式Linux系统中ARM汇编语言的使用方法
    SPP-学习笔记
    python学习-----logging模块
    百度智能云千帆大模型丨未来人手必备的代码助手
    初学vue.js
  • 原文地址:https://www.cnblogs.com/qjds/p/16545106.html