• 简单快速搞定会话技术Cookie&Seesion


    “从来不跌倒不算光彩,每次跌倒后能再站起来,才是最大的荣耀。”你好,我是梦阳辰,快和我一起学习起来吧!

    01.概述

    会话技术
    Web应用中的会话过程类似于生活中的打电话过程,它指的是一个客户端(浏览器)于web服务器之间连续发生的一系列请求和响应的过程。

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

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

    功能:在一次会话的范围内的多次请求间,共享数据。

    方式:
    客户端会话技术:Cookie

    服务器端会话技术: Session

    02.Cookie快速入门

    1.概念:客户端会话技术,将数据保留在客户端。

    快速入门
    使用步骤:
    1.创建Cookie对象,绑定数据。

    new Cookie(String name, String value) 
    

    2.发送Cookie(发给浏览器)

    reponse.addCookie(Cookie cookie);
    

    3.获取Cookie,拿到数据(浏览器将cookie包装在请求中,服务器就可以拿到cookie)

    Cookie[]  request.getCookies();
    

    测试:

    @WebServlet("/ServletCookieTest1")
    public class ServletCookieTest1 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1.创建Cookie对象
            Cookie c  =new Cookie("name","meng");
            //发送Cookie
            response.addCookie(c);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
        }
    }
    
    
    @WebServlet("/ServletCookieTest2")
    public class ServletCookieTest2 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            //3.获取Cookie
            Cookie[] cs  = request.getCookies();
            if(cs!=null){
                for (Cookie c :cs){
                    String name = c.getName();
                    String value = c.getValue();
                    System.out.println(name+":"+value);
                }
            }
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
        }
    }
    
    

    结果:访问1,再访问2后。
    在这里插入图片描述
    在这里插入图片描述

    03.Cookie原理分析与应用

    1.原理图解:
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    2.cookie能否发送多个cookie?
    可以!
    可以创建多个Cookie对象,使用response调用多次addCookie方法发送Cookie即可。

    @WebServlet("/ServletCookieTest3")
    public class ServletCookieTest3 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1.创建Cookie对象
            Cookie c1  =new Cookie("name","meng");
            Cookie c2  =new Cookie("firstName","YangChen");
    
            //发送Cookie
            response.addCookie(c1);
            response.addCookie(c2);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
        }
    }
    
    

    在这里插入图片描述
    在这里插入图片描述

    3.cookie在浏览器中保存多长的时间?
    1.默认情况下,当浏览器关闭后,Cookie数据被销毁(在浏览器内存中)。

    2.在浏览器关闭后,仍然保存下来。
    持久化存储:

    setMaxAge(int seconds);
    

    1.正数:将Cookie数据写到硬盘文件中,持久化存储,cookie存活时间。

    2.负数:默认值。

    3.零:删除cookie信息。

    @WebServlet("/ServletCookieTest4")
    public class ServletCookieTest4 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1.创建Cookie对象
            Cookie c  =new Cookie("msg","setMaxAge");
    
            //2.设置存活时间
            c.setMaxAge(60);
            //发送Cookie
            response.addCookie(c);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
        }
    }
    

    4.cookie能不能存储中文数据?
    Tomcat8之前cookie中不能支持中文数据。
    需要将中文数据转码------------------一般用url编码。

    value = URLEncoder.encode(value,"utf-8");
    cookie.setValue(value);
    //输出时还需要解码
    value =URLDecoder.decode(value,"utf-8");
    

    Tomcat8之后完全没得问题(但对特殊字符还是不行)。

    5.cookie数据共享范围有多大?
    假设在一个tomcat服务器中,部署了多个web项目,那么在这些项目中cookie能不能共享?

    默认情况下cookie不能共享。

    setPath(String path):设置cookie的获取范围。
    默认情况下,设置当前的虚拟目录(项目)。
    如果要共享,则可以将path设置为“/”。(根路径)

    不同的tomcat服务器间Cookie共享问题?

    setDomain(String path):
    
    
    如果设置以及域名相同,那么多个服务器之间cookie可以共享
    setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie
    可以共享
    

    Cookie的特定和作用
    1.cookie存储数据在客户端浏览器(不安全)。

    2.浏览器对于单个cookie的大小有限制(4kb)以及同一个域名下的总cookie数量也有限制。

    3.cookie一般用于存储少量的不太敏感数据。

    4.在不登录的情况下,完成对服务器的身份识别。

    04.Cookie案例

    1.记录上一次访问网站的时间。
    需求:
    1.访问一个servlet,如果是第一次访问,则提示:您好,欢迎您首次访问。2.如果不是第一次访问,则提示∶欢迎回来,您上次访问时间为:显示时间字符串

    分析
    1.可以采用cookie来完成

    2.在服务器中的servlet判断是否有一个名为lastTime的cookie

    有:不是第一次访问.

    响应数据:欢迎回来,您上次访问时间为:2018年6月10日11:50:202.写cookie

    2.没有:是第一次访问。

    1.响应数据:您好,欢迎您首次访问

    2.写回cookie : lastTime=2020年11月13

    @WebServlet("/ServletCookieTest5")
    public class ServletCookieTest5 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
            PrintWriter out = response.getWriter();
            //1.获取所有的Cookie
            Cookie[] cookies = request.getCookies();
            //2.遍历Cookie数组
            boolean flag= false;//没有Cookie为lastTime
            if(cookies!=null&&cookies.length>0){
                for(Cookie cookie :cookies){
                    //3.获取Cookie的名字
                    String name = cookie.getName();
                    //4.判断Cookie名称是否是:lastTime
                    if("lastTime".equals(name)){
                        flag = true;
                        //5.有该Cookie,则不是第一次访问
                        //获取当前时间的字符串,重新设置Cookie的值,重新发送Cookie
                        Date date = new Date();
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        String str_date = sdf.format(date);
                        str_date = URLEncoder.encode(str_date,"utf-8");
                        cookie.setValue(str_date);
                        //设置Cookie的存活时间
                        cookie.setMaxAge(60*60*24*30);//一个月
                        response.addCookie(cookie);
                        //响应数据
                        //获取Cookie的value,时间
                        String value = cookie.getValue();
                        value = URLDecoder.decode(value,"utf-8");
                        out.print("欢迎回来,你上次访问的时间是:"+value);
                        break;
                    }
                }
            }
            if(cookies==null||cookies.length==0||flag==false){
                //没有,则是第一次访问
                Date date = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String str_date = sdf.format(date);
                str_date = URLEncoder.encode(str_date,"utf-8");
                Cookie cookie  = new Cookie("lastTime",str_date);
                //设置Cookie的存活时间
                cookie.setMaxAge(60*60*24*30);//一个月
                response.addCookie(cookie);
                out.print("你好,欢迎你首次访问!");
            }
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
        }
    }```
    
    # 05.Session
    1.**概念**:服务器端会话技术,在==一次会话的多次请求间==共享数据,将数据保存在服务器端的对象中。(HttpSession)
    
    当浏览器访问web服务器时,Servlet容器就会创建一个==Session对象==和==ID属性==,其中Session对象就相当于病历档案,ID就相当于就诊卡号。当客户端后续访问服务器时,只要将标识号传递给服务器,服务器就能判断出该请求是那个客户端发送的,从而选择与之对应的session对象为其服务。
    
    由于客户端需要接收,记录和回送Sesssion对象的ID属性,因此,Session需要借助Cookie技术来传递ID属性。
    
    在一次会话中:cookie保存了用户的浏览数据,session对象同样也保存了用户浏览数据,通过ID属性确认用户的身份。
    **2.快速入门:**
    2.1获取HttpSession对象:
    
    ```java
    HttpSession session = request.getSession();
    

    2.2使用HttpSession对象:

    Object getAttribute(String name);
    void setAttrebute(String name,Object value);
    void removeAttribute(String name);
    
    @WebServlet("/ServletSessionTest1")
    public class ServletSessionTest1 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            HttpSession session = request.getSession();
    
            //存储数据
            session.setAttribute("user","MengYangChen");
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
        }
    }
    
    @WebServlet("/ServletSessionTest2")
    public class ServletSessionTest2 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //获取session对象
            HttpSession session = request.getSession();
            //取数据
            String user = (String)session.getAttribute("user");
            System.out.println(user);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
        }
    }
    
    

    在这里插入图片描述

    06.Session原理分析与应用

    session是依赖于cookie的。
    在这里插入图片描述
    1.当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
    默认认情况下不是。(因为服务器依靠ID属性确认客户端为哪个session对象,而ID属性保存在客户端的cookie中,当浏览器关闭时,cookie也就默认删除)

    如果需要相同,则可以创建cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。

    Cookie c = new Cookie( "SESSIONID" ,session.getId());
    c.setMaxAge(60*60) ;
    response.addcookie(c);
    

    测试:

    @WebServlet("/ServletSessionTest3")
    public class ServletSessionTest3 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1.获取session
            HttpSession session  = request.getSession();
    
            //期望客户端关闭后,session也能相同
            Cookie c = new Cookie("JSESSIONID",session.getId());
            c.setMaxAge(60*60);//1小时
    
            response.addCookie(c);
            System.out.println(session);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
        }
    }
    
    

    2.客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
    不是同一个,但是要确保数据不丢失。

    session的钝化:在服务器正常关闭之前,将session对象序列化到硬盘上。

    session的活化:在服务器启动后,将session文件转化为内存中的session对象即可。
    Tomcat已经为我们实现了钝化和活化的过程。

    3. session的失效时间?
    服务器关闭。

    sesion对象调用invalidate()方法。

    Tomcat服务器session默认失效时间30分钟(可以在配置文件中配置)。

    4.Seesion的特点
    用于存储一次会话的多次请求数据,存在于服务器端。

    session可以存储任意类型,任意大小的数据。

    5.session与cookie的区别:
    session存储数据在服务器端,Cookie在客户端。

    session没有数据大小限制,Cookie有。

    sesion数据安全,Cookie相对于不安全。

    07.Session验证码案例

    案例需求:
    1.访问带有验证码的登录页面login.jsp。

    2.用户输入用户名,密码以及验证码。

    如果用户名和密码输人有误,跳转登录页面,提示:用户名或密码错误。

    如果验证码输入有误,跳转登录页面,提示:验证码错误。

    如果全部输人正确,则跳转到主页success.jsp,显示∶用户名,欢迎您。

    分析:
    在这里插入图片描述
    登录:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    <html>
    <head>
        <title>用户登录</title>
        <script src="../tool/jquery-3.5.1.min.js"></script>
    </head>
    <body>
        <form class="fm">
            <div>
                <label>用户:</label>
                <input type="text" name="userName" id="userName"/>
            </div>
    
            <div>
                <label>密码:</label>
                <input type="password" name="passWord" id="passWord"/>
            </div>
    
            <div>
                <label>验证码:</label>
                <input type="text" name="checkCode" id="checkCode"/><br>
                <img src="/First/IdentifyingCodeServlet" id="img"></img>
            </div>
            <input type="button" id="btn" value="确认">
        </form>
        <p style="color: red" ></p>
        <script>
            $(function () {
                $("img").click(function () {
                    this.src="/First/IdentifyingCodeServlet?time="+new Date().getTime();//加上时间戳欺骗浏览器缓存
                });
    
                $("#btn").click(function () {
                    var fmData = $(".fm").serialize();
                    $.get(
                        "/First/LoginServlet",
                        fmData,
                        function (data) {//使用ajax需要在前端实现跳转页面
                            $("p").html(data);
                        }
                    );
                });
            });
        </script>
    </body>
    </html>
    
    

    成功页面:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>登录成功页面</title>
    </head>
    <body>
            <h1><%=request.getSession().getAttribute("userName") %>,欢迎你!</h1>
    </body>
    </html>
    
    

    后端:

    package IdentifyingCode;
    
    import javax.imageio.ImageIO;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.Random;
    
    
    @WebServlet("/IdentifyingCodeServlet")
    public class IdentifyingCodeServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            int width = 100;
            int height = 50;
            //1.创建一对象,在内存中的图片(验证码图片对象)
            BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
            //2.美化图片
            //2.1填充背景色
            Graphics g = image.getGraphics();
            g.setColor(Color.pink);
            g.fillRect(0,0,100,50);//填充矩形
    
            //2.2画边框
            g.setColor(Color.yellow);
            g.drawRect(0,0,width-1,height-1);
    
            String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
            //生成随机角标
            Random ran  = new Random();
    
            StringBuilder sb = new StringBuilder();//存储验证码的值
            for(int i=1;i<=4;i++){
                int index = ran.nextInt(str.length());
                char ch = str.charAt(index);//随机字符
                sb.append(ch);
                //2.3写验证码
    
                g.setColor(Color.blue);
                g.drawString(""+ch,width/5*i,height/2);
            }
            String checkCode_session = sb.toString();
            //将验证码存入session
            request.getSession().setAttribute("checkCode_session",checkCode_session);
    
    
            //2.4画干扰线,防识别
            //随机生成坐标点
            for(int i=0;i<8;i++){
                int x1 =ran.nextInt(width);
                int x2 =ran.nextInt(width);
                int y1 =ran.nextInt(height);
                int y2 =ran.nextInt(height);
                g.setColor(Color.green);
                g.drawLine(x1,y1,x2,y2);
            }
    
            //3.将图片输出到页面展示
            ImageIO.write(image,"jpg",response.getOutputStream());
    
    
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
        }
    }
    
    
    package IdentifyingCode;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.io.PrintWriter;
    
    @WebServlet("/LoginServlet")
    public class LoginServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            //1.设置request编码
            request.setCharacterEncoding("utf-8");
            //2.获取参数Map(简化获取参数)
            response.setContentType("text/html;charset=utf-8");
            PrintWriter out = response.getWriter();
            String userName = request.getParameter("userName");
            String passWord = request.getParameter("passWord");
            String checkCode = request.getParameter("checkCode");
    
            //先判断验证码是否正确
            //先获取生成的验证码
            HttpSession session = request.getSession();
            String checkCode_session =(String)session.getAttribute("checkCode_session");
            //用完就删除验证码
            session.removeAttribute("checkCode_session");
            if(checkCode_session!=null&&checkCode_session.equalsIgnoreCase(checkCode)) {//忽略大小写的比较
                //判断用户名和密码是否一致
                if("MengYangChen".equals(userName)&&"123456".equals(passWord)){//简单书写,原则需要查询数据库
                    //登录成功
                    //存储信息,用户信息
                    session.setAttribute("userName",userName);
                    //重定向到sussess.jsp
                    response.sendRedirect(request.getContextPath()+"/html/success.jsp");
                }else{//登录失败
                    //存储提示信息到request
                    //request.setAttribute("login_error","用户名或密码错误!");
                    out.print("用户名或密码错误!");
                    //转发到登录页面
                    //request.getRequestDispatcher("html/login.jsp").forward(request,response);
    
                }
    
            }else{
                //验证码不一致
    
                //存储提示信息到request
                //request.setAttribute("cc_error","验证码错误");
                out.print("验证码错误!");
                //转发到登录页面
                //request.getRequestDispatcher("/html/login.jsp").forward(request,response);
    
            }
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
        }
    }
    
    

    结果:
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    以梦为马,不负韶华。
  • 相关阅读:
    ubuntu 防止软件包自动更新
    记录一个开头带有&#x的特征数据的解码
    从一次失败的微信小程序抓包、反编译经历中学习反思
    Python爬虫处理奇葩的请求参数payload
    python爬虫
    python爬虫处理在线预览的pdf文档
    python高级—— 从趟过的坑中聊聊爬虫、反爬、反反爬,附送一套高级爬虫试题
    djangorestframework+vue-cli+axios,为axios添加token作为headers踩坑记
    django 问题综合
    vue(9)—— 组件化开发
  • 原文地址:https://www.cnblogs.com/huangjiahuan1314520/p/13985990.html
Copyright © 2020-2023  润新知