JavaWeb - Cookie & Session

Cookie & Session

第一章-会话的概念

知识点-会话的概念

1. 概述

1.1会话的概念

​ 用户打开浏览器,浏览不同的网页(资源),发出多个请求,直到关闭浏览器的过程,称为一次会话(多次请求). 如同打电话.

​ 我们在会话的过程(多次请求)之中,用户可能会产生一些数据,这些数据话有的需要保存起来的,我们就可以通过会话技术保存用户各自的数据

1.2为什么要使用会话技术

​ 保存一次通话过程中的数据!

​ 会话技术中数据的保存方式:

​ 浏览器存储会话数据:cookie

​ 服务器存储会话数据:session

1.3常用的会话技术
1.3.1cookie(记住用户名密码)

cookie是客户端(浏览器)的技术,用户浏览的信息以键值对(key=value)的形式保存在浏览器上。如果没有关闭浏览器,再次访问服务器,会把cookie带到服务端,服务端就可以做响应的处理。

1.3.2session(记住登录用户名 购物车)

​ ==session是服务器端的技术。==服务器为每一个浏览器开辟一块内存空间,即session。由于内存空间是每一个浏览器独享的,所有用户在访问的时候,可以把信息保存在session对象中。同时,每一个session对象都对应一个sessionId,服务器把sessionId写到cookie中,再次访问的时候,浏览器会把cookie(sessionId)带过来,找到对应的session对象。

2. 小结

  1. 会话概念
    1. 会话就相当于一次通话,表示从浏览器和服务器的一次通话过程【多次请求和响应】
    2. 会话建立:打开浏览器第一次请求服务器
    3. 会话结束:直到浏览器和服务器有一方关闭
  2. 为什么要使用会话技术?
    1. 要保持一次会话中的重要数据
    2. 客户端会话技术:cookie 表示将数据保存在浏览器
    3. 服务端会话技术:session 表示将数据保存在服务器

第二章-Cookie

知识点-Cookie的概念和作用

1. 讲解

1.1 Cookie的概念

​ cookie:客户端的会话技术,保存数据在浏览器!

​ cookie:一个名称和一个值 一些可选属性 cookie存储的数据大小和个数都有限

​ cookie写入:response.addCookie() 将cookie从服务器 写入到浏览器

返回cookie
    1. cookie返回之后,会被设置在响应头里面,形如:
        Set-Cookie: address=shenzhen
    2. 可以返回多个cookie
        Set-Cookie: address=shenzhen
        Set-Cookie: username=zhangsan
    3. 如果cookie的name一样,那么后面的内容会覆盖前面的内容。

​ cookie获取:request.getCookies()

1.2 Cookie的作用
  1. 在浏览器中存放数据
  2. 将浏览器中存放的数据携带到服务器
1.3 Cookie的应用场景

1.记住用户名
当我们在用户名的输入框中输入完用户名后,浏览器记录用户名,下一次再访问登录页面时,用户名自动填充到用户名的输入框.

2.自动登录(记住用户名和密码)
当用户在淘宝网站登录成功后,浏览器会记录登录成功的用户名和密码,下次再访问该网站时,自动完成登录功能.
以上这些场景都是使用会话cookie实现的,将上次的信息保存到了cookie中,下次直接从cookie中获取数据信息

3.保存网站的上次访问时间
我们访问网站的时候,通常会看到网站上显示上次访问时间,这些信息就是在用户访问网站的时候保存在cookie中的

4.保存电影的播放进度

​ 在网页上播放电影的时候,如果中途退出浏览器了,下载再打开浏览器播放同一部电影的时候,会自动跳转到上次退出时候的进度,因为在播放的时候会将播放进度保存到cookie中

2. 小结

cookie:客户端会话技术,将数据保存在浏览器。使用cookie保存用户各自的数据

cookie特点:

1. cookie保存会话数据在客户端浏览器
2. cookie保存数据大小以及个数有限

cookie使用场景:

  1. 记住用户名和密码【登录前】
  2. 自动登录
  3. 记录上次访问时间
  4. 记录电影播放进度

知识点-Cookie的快速入门【重点】

1.目标

  • 掌握Cookie的基本使用

2.路径

  1. 相关的API
  2. 入门代码

3.概述

3.1相关的API
  • 创建一个Cookie对象(cookie只能保存字符串数据。可以保存中文 但是要求tomcat版本8.5+)
new Cookie(String name,String value);
  • 把cookie写入浏览器
response.addCookie(cookie); 
  • 获得浏览器带过来的所有Cookie:
request.getCookies() ; //得到所有的cookie对象。是一个数组,开发中根据key得到目标cookie
  • cookie的 API
cookie.getName() ; //返回cookie中设置的name
cookie.getValue(); //返回cookie中设置的value
3.2入门代码
@WebServlet("/cookie01")
public class CookieServlet01 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("CookieServlet01...");
        //设置cookie  响应给客户端浏览器
        //1.创建Cookie对象
        Cookie cookie = new Cookie("name", "shuaige");
        //2.使用response将cookie输出到客户端浏览器
        response.addCookie(cookie);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
@WebServlet("/cookie02")
public class CookieServlet02 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("CookieServlet02...");

        //3.获取客户端请求携带的cookie数据
        //	<1>浏览器来访问的时候,如果它有cookie的话,会携带cookie 过来;如果没有携带过来,那么 request.getCookies 将会返回 null
        //	<2>如果有多个cookie带过来,那么会一起被设置在请求头里面:
        //      Cookie: username=zhangsan; address=beijing
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            System.out.println(cookie.getName()+" "+cookie.getValue());
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
3.3 cookie工具类抽取
package com.itheima.utils;

import javax.servlet.http.Cookie;

public class CookieUtils {

    //根据cookie的name获取cookie的value
    public static String getCookieValue(Cookie[] cookies,String name){
        //如果cookies数组 为null 或者 cookie的name为null或空串 直接返回null
        if (cookies==null || name==null || name.equals("")){
            return null;
        }
        for (Cookie cookie : cookies) {
            if(cookie.getName().equals(name)){
                return cookie.getValue();
            }
        }
        return null;
    }
}

4.小结

  1. cookie的特点
    1. cookie是一门客户端会话技术,保存数据在客户端浏览器
    2. cookie在第一次请求时没有,通过服务器以响应头的方式写给浏览器,在浏览器第二次发送 请求时,就会携带cookie到服务器
    3. cookie存储的字符串数据
    4. cookie存储的大小以及个数有限
    5. cookie存储数据不安全 因此cookie会存储一些私人数据或不重要的数据
  2. cookie使用的API
    1. 创建Cookie对象:Cookie cookie = new Cookie(String name,String value);
    2. cookie写入:response.addCookie(cookie);
    3. cookie获取:Cookie[] cookies = request.getCookies();
    4. 获取cookie名称:cookie.getName();
    5. 获取cookie值:cookie.getValue();

知识点-Cookie进阶【重点】

1.目标

  • 掌握设置Cookie的有效时长和路径

2.步骤

  • cookie的分类【cookie的有效时间】
  • cookie的有效路径

3.概述

3.1cookie的分类

session中的数据是存在内存中的,关机了就没了

浏览器不关,服务器关闭后,cookies暂时还在,如果关闭浏览器再打开就没了

cookie要分情况,如果不设置有效期那么默认是session级别,浏览器关了就没了;如果设置了有效期,到时候到期了,其实是没法通过代码删除的,它会一直存在浏览器里边,只能用户手动删。服务器只能删除正处于有效期内的cookie,因为在有效期内,客户端每次发起请求都还是会带着cookie,如果过期了就不会带了,并且浏览器会标识每个cookie是属于哪个网站的,以及分好组了,所以发起请求的时候,一个网站的cookie是不会带到另一个网站的。

  • 会话级别cookie

​ 在默认的情况下,当浏览器进程结束(浏览器关闭,会话结束)的时候,cookie就会消失。

  • 持久性cookie

    ​ 给cookie设置有效期.cookie.setMaxAge(int expiry) :时间是秒

    ​ 负数:默认 会话级别。代表Cookie数据存到浏览器关闭(保存在浏览器文件中)。

        正整数:以秒为单位保存数据有有效时间(把缓存数据保存到磁盘中)    
    

    ​ 0:代表删除Cookie.如果要删除Cookie要确保路径一致

    @WebServlet("/cookie03")
    public class CookieServlet03 extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("CookieServlet03...");
            //设置cookie  响应给客户端浏览器
            //1.创建Cookie对象
            Cookie cookie = new Cookie("name", "shuaige");
    
            //设置cookie的有效时间  -1:默认会话级别,浏览器一关闭cookie消失  0:删除cookie
            //cookie.setMaxAge(60*2); 
            //单位是 秒
            cookie.setMaxAge(0);
    
            //2.使用response将cookie输出到客户端浏览器
            response.addCookie(cookie);
        }
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    
3.2cookie设置有效路径
setPath(String url) ;设置路径

​ 有效路径作用 :

  1. 保证不会携带别的网站/项目里面的cookie到我们自己的项目(一个是域名ip地址隔离,一个路径隔离)
  2. 如果路径不一样, cookie的name可以相同
  3. 保证自己的项目可以合理的利用自己项目的cookie(默认路径: /项目部署路径 eg:/day24)
  • 默认路径,例如:

    • 访问http://localhost:8080/day24/demo01; cookie默认路径 /day24
    • 访问http://localhost:8080/day24/aaa/demo01; cookie默认路径 /day24/aaa

    • 访问http://localhost:8080/day24/aaa/bbb/demo01; cookie默认路径 /day24/aaa/bbb

  • 携带Cookie需要的条件: 只有当访问资源的url上一级目录与此cookie的有效path完全匹配的时候,才会携带这个cookie; url上一级目录如果是cookie有效路径的子目录也可以获取到反之不会.

    • eg:setPath(“/”)

      • http://localhost:8080/day23/cookieDemo /day23是/的子目录
    • http://localhost:8080/day24/cookieDemo02 /day24是/的子目录

    • eg: 设置cookie的路径 /day24/demo02

      下次访问路径:http://localhost:8080/day24/demo02/abc/ccc; cookie是可以带过来

      下次访问路径:http://localhost:8080/day24/demo03; cookie带不过来

  • cookie的路径通常设置 / 或者为发布项目名设置的有效是 /day24. 当前项目下的Servlet都可以使用该cookie. 一般这么设置: cookie.setPath(request.getContextPath());

    只要是当前项目里面的资源 路径必须包含项目名路径.

    /**
     * cookie的基本使用
     */
    @WebServlet("/aa/cookie04")
    public class CookieDemo04 extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("CookieDemo04...");
            //cookie的基本使用
            //1.创建Cookie对象
    
            //cookie使用细节1:cookie原来不可以存中文和特殊字符 tomcat8.5版本之后可以存储中文但是依然不能存储特殊字符
            //cookie如果想存储特殊字符  需要将cookie的value使用URLEncoder进行编码,获取时就需要使用URLDecoder解码
            //cookie存入时编码:URLEncoder.encode(value,"UTF-8");
            //cookie取出时解码:URLDecoder.decode(value,"UTF-8");
            String value = URLEncoder.encode("黄 文 龙", "UTF-8");
            Cookie cookie = new Cookie("name",value);
    
            //cookie使用细节2:可以一次写入多个cookie
            Cookie cookie1 = new Cookie("address", "深圳");
    
    
            /*设置有效路径:cookie.setPath();
                如果不设置cookie有效路径:默认就是是当前servlet的资源路径
                    eg:/day25/cookie01     -->    /day25
                    eg:/day25/aa/cookie04  -->    /day25/aa
                获取cookie所在的servlet资源路径只有与cookie路径同级或在其子目录下才能获取到cookie
                cookie的路径一般设置为当前项目虚拟路径,这样就可以实现cookie在当前项目下进行共享了【也就是在任何地方Servlet中都可以获取cookie】
                最后:这里大家只作了解  一般我们不设置cookie的有效路径  实际使用中一般只设置有效时间
             */
            cookie.setPath(request.getContextPath());
            cookie1.setPath("/day25");
    
            //2.使用response将cookie写入到浏览器
            response.addCookie(cookie);
            response.addCookie(cookie1);
        }
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    

4.小结

  1. Cookie的有效时长:cookie.setMaxAge(int seconds)
    1. -1:默认值,表示会话级别 浏览器一关闭则cookie删除
    2. 0:删除cookie
    3. 正整数:表示cookie的有效时间 单位是秒
  2. cookie的有效路径:cookie.setPath(String path);
    1. 不同路径下的cookie名称可以一样
    2. cookie默认路径是当前Servlet所在资源路径
    3. cookie有效路径一般设置为当前项目的虚拟路径:setPath(request.getContextPath());
    4. cookie存储设置路径,在其路径同级目录和子目录下都可以访问到该cookie
  3. cookie存储中文及特殊字符
    1. tomcat已经解决了cookie中文存储,但是仍然不能存储特殊字符,比如空格…
    2. 存储时编码:URLEncoder.encode(value,“UTF-8”);
    3. 获取时解码:URLDecoder.decode(value,“UTF-8”);
  4. cookie可以一次存储多个

5. cookie设置中文

/*
     cookie设置中文
 */
@WebServlet("/demo04")
public class DemoServlet04 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//也可以用URLEncoder与URLDecoder进行编码和解码
        String s = Base64.getEncoder().encodeToString("=深圳=".getBytes());
        System.out.println("s = " + s);
        //1. 创建cookie对象
        Cookie cookie = new Cookie("address", s);

        //2. 返回cookie
        response.addCookie(cookie);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

案例-记录用户各自的上次访问时间

1.需求

​ 在访问一个资源的时候,展示上次访问的时间

​ 若是第一次访问则展示:你是第一次访问,若不是第一次则展示:你上次访问的时间是:xxxx

2.分析

通过cookie判断是否第一次登录

3.代码实现


@WebServlet("/rem")
public class RememberServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //请求响应中文乱码处理
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        Cookie[] cookies = request.getCookies();
        //1.根据cookie的name【lastTime】获取上次访问时间
        String lastTime = CookieUtils.getCookieValue(cookies, "lastTime");
        //2.判断value
        if(lastTime==null){
            //3.1:value==null:第一次访问       
            //获取当前时间,记录在cookie中,写入到浏览器     
            String dateStr = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
            Cookie cookie = new Cookie("lastTime", URLEncoder.encode(dateStr,"UTF-8"));
            response.addCookie(cookie);
            //响应浏览器  用户 你是第一次访问
            response.getWriter().print("你是第一次访问!");
        }else{
            //3.2:value!=null:显示上次访问时间       
            //获取当前时间,记录在cookie中,写入到浏览器 
            String dateStr = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
            Cookie cookie = new Cookie("lastTime", URLEncoder.encode(dateStr,"UTF-8"));
            response.addCookie(cookie);
            //响应浏览器 用户  你上次访问的时间
            response.getWriter().print("你上次访问时间是:"+ URLDecoder.decode(lastTime,"UTF-8"));
        }

    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

第三章-Session

知识点-session概述

1.目标

  • 掌握Session的基本概念 以及和cookie的区别

2.路径

  1. session概述
  2. cookie和Session的不同
  3. Session的执行原理

3.讲解

3.1session概述

session是服务器端的会话技术,用于保存数据在请求间实现数据共享。

​ session是服务器端的会话技术。服务器为每一个浏览器开辟一块内存空间,即session对象。由于session对象是每一个浏览器特有的,所以用户的记录可以存放在session对象中。同时,每一个session对象都对应一个sessionId,服务器把sessionId写到cookie中,再次访问的时候,浏览器把sessionId带过来,找到对应的session对象

3.2cookie和Session的不同
  • Session将数据保存在服务器端,cookie将数据保存在客户端浏览器
  • session一般保存比较重要的数据,cookie保存的相对不重要比较私人的数据
  • session存储的是对象Object,cookie存储的是字符串数据
  • session在数据的存储上没有限制,cookie存储数据量大小以及个数都有限制
  • session是基于cookie实现的
3.3Session的执行原理

​ 1、获得cookie中传递过来的SessionId(cookie)(浏览器请求服务器会将该项目路径下的cookie带过去)

​ 2、如果Cookie中没有sessionid,则创建session对象(第一次调用request.getSession()创建Session对象

​ 3、如果Cookie中有sessionid,找指定的session对象

​ 如果有sessionid并且session对象存在,则直接使用

如果有sessionid,但session对象销毁了,则执行第二步

注意:

  1. 第一次调用request.getSession()才会创建session对象,不调用则session对象不存在
  2. session对象的生命周期范围就是从第一次调用request.getSession(),session对象被创建,当关闭浏览器,session对象被持久化到硬盘
  3. session对象在创建时,会自动产生sessionId,由服务器通过cookie方式写入到浏览器缓存中,该cookie的name是JSESSIONID

4.小结

​ session:服务器端会话技术,保存数据在服务器内存中。

​ cookie和session的区别:

		1. cookie存储会话数据在客户端浏览器,session存储数据在服务器
		2. cookie存储的是字符串数据,session存储的是Object对象
		3. cookie存储的数据量大小和个数有限,session没有限制
		4. cookie一般存储不重要的数据,session存储重要数据
		5. session基于Cookie实现的

​ session工作原理:

1. 第一次请求,通过request.getSession()创建session对象
2. 创建完session对象时,会生成sessionId,保存到cookie中响应给客户端浏览器
3. 第二次请求时,客户端浏览器会携带sessionId到服务器,服务器就根据sessionId找到对应的session对象使用	

知识点-Session的基本使用【重点】

1.目标

  • 掌握Session的使用,

2.路径

  • Session基本使用

3.概述

​ ServletContext:整个应用

​ request:一次请求

​ Session使用:作为域对象存储数据使用

范围: 一次会话(多次请求) 保存用户各自的数据(以浏览器为单位)

  • request.getSession(); 获得session(如果第一次调用的时候其实是创建session,第一次之后通过sessionId找到session进行使用)

  • Object getAttribute(String name) ;获取值

  • void setAttribute(String name, Object value) ;存储值

  • void removeAttribute(String name) ;移除

  • session的基本使用
         存值:
                 session.setAttribute("name", "张三");
         取值:
                 String name = (String) session.getAttribute("name");
         删除值:
                 session.removeAttribute("name");
        
      session 是如何实现数据共享的呢?
         1. 当第一次请求的代码里面存在request.getSession这句话的时候,就会创建一个新的session对象。
         2. 并且Tomcat会自动的给这次响应设置cookie,把session的id设置到cookie里面去
             2.1 Tomcat设置的这个cookie是一个临时性的cookie。
             2.2 这个cookie的名字: JSESSIONID
             2.3 这也就形成了关闭浏览器之后,cookie就消失了。再次访问,就是一次新的会话。
             2.4 如果希望关闭浏览器之后,重新打开还能使用之前的session,那么需要手动返回cookie
                 a. 把cookie设置有效期。
                 b. cookie的名字必须是JSESSIONID , cookie的值,就是session的id值。
         3. 当再次请求的时候,浏览器会自动带过来session的id值。代码里面也有这句话: request.getSession
             3.1 此时就不会创建新的session,而是根据id值去找原来的对象|区域。找到就返回.
             3.2 找不到就会创建新的对象.
    
@WebServlet("/session01")
public class SessionServlet01 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("SessionServlet01...");

        //使用Session共享数据  范围:一次会话:多次请求中
        //1.获取Session对象
        HttpSession session = request.getSession();
        //2.调用方法存储数据
        session.setAttribute("sname","优秀");
        System.out.println("session01:"+session);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
@WebServlet("/session02")
public class SessionServlet02 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        System.out.println("SessionServlet02...");
        //获取session中的共享数据
        HttpSession session = request.getSession();
        Object sname = session.getAttribute("sname");
        System.out.println("sname = " + sname);
        System.out.println("session02:"+session);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
session有效期

方式一:tomcat设置session失效时间,默认30min

conf/web.xml

方式二:设置失效时间 setMaxInactiveInterval(); 单位是秒

方式三:手动设置失效 invalidate();

@WebServlet("/session03")
public class SessionServlet03 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        System.out.println("SessionServlet03...");
        //获取session中的共享数据
        HttpSession session = request.getSession();

        //设置session失效
        //方式二:设置失效时间 单位是秒 正数表示有效时间  负数表示永远不会过时
        //session.setMaxInactiveInterval(20);
        //方式三:手动设置失效 立即失效
        session.invalidate();
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
session持久化
  1. 浏览器关闭,会话结束,此时session对象有没有被销毁?没有
    session对象虽然还存在,但是找不到了!因为新打开浏览器发起请求,产生了一个新的sessionId,找不到 原来的session对象了。

    /**
     * 使用cookie持久化session
     */
    @WebServlet("/session04")
    public class SessionServlet04 extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("SessionServlet01...");
    
            //使用Session共享数据  范围:一次会话:多次请求中
            //1.获取Session对象
            HttpSession session = request.getSession();
            //2.调用方法存储数据
            session.setAttribute("sname","优秀");
            System.out.println("session01:"+session.getId());
            System.out.println("session01:"+session);
    
            //将sessionId存入 cookie中
            Cookie cookie = new Cookie("JSESSIONID",session.getId());
            cookie.setMaxAge(60);
            response.addCookie(cookie);
        }
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    
  2. 如果服务器正常关闭,浏览器没有关闭,session对象有没有被销毁?还能不能获取到session中存储的数据?

    session钝化:指的是服务器正常关闭,会自动将session数据持久化保存到硬盘的文件上。

    session活化:指的是服务器正常启动,会将持久化的session数据加载到内存中,重新创建一个session对象,存储活化后的数据,但是sessionId没有改变。

    注意:session的钝化和活化是服务器自动完成的,我们了解服务器的这种机制即可。

4.小结

  1. session基本使用 范围:一次会话【多次请求】
    1. 获取session对象 :request.getSession();
    2. 存值:session.setAttribute(key,value);
    3. 取值:session.getAttribute(key);
    4. 移除:session.removeAttribute(key);

  2. session有效期设置

    1. 设置有效时间:session.setMaxInactiveInterval(int seconds);
    2. 手动设置失效:session.invalidate();

知识点-三个域对象比较

1.目标

  • 掌握三个域对象的不同

2.路径

  1. 三个域对象比较
  2. 三个域对象怎么选择

3.概述

3.1三个域对象比较
域对象创建销毁作用范围应用场景
ServletContext服务器启动服务器正常关闭/项目从服务器移除整个项目记录访问次数,聊天室
HttpSession第一次调用request.getSession()方法session过期(默认30分钟)/调用invalidate()方法/服务器正常关闭会话(多次请求)验证码校验, ==保存用户登录状态==等
HttpServletRequest来了请求响应这个请求(或者请求已经接收了)一次请求servletA和jsp(servletB)之间数据传递(转发的时候存数据)

范围:httpServletReques【一次请求】–> HttpSession【一次会话】 --> ServletContext【整个应用】

基本使用:

​ 存储数据:setAttribute(String name,Object value);

​ 获取数据:getAttribute(String name);

​ 移除数据:RemoveAttribute(String name);

3.2三个域对象怎么选择?
  1. 常规选择:一般使用范围最小的能完成就选择最小的
  2. 具体请求选择:
    1. 转发:使用request作用域 重定向:使用session
    2. 查询:使用request作用域
    3. 根据范围:一次请求:【request】 一次会话:【session】 整个应用:【ServletContext】

案例-一次性验证码校验

1.需求

​ 在网站登录的时候,生成一个验证码.登录的时候对验证码进行校验.

2.分析

2.1:创建登录页面login.html

2.2:验证码图片生成

​ 1.导入验证码生成工具类CheckCodeUtil

​ 2.编写验证码生成Servlet CodeServlet

​ 生成验证码

​ 响应给页面

2.3:填写登录信息以及验证码,进行验证码比对登录LoginServlet

3.实现

  • 登录页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--
    login.html:http://localhost:8080/login.html
    CheckcodeServlet:http://localhost:8080/checkcodeServlet
-->
<center>
    <h1>用户登录</h1>
    <form action="login" method="post">
        姓名:<input type="text" name="username"/><br/>
        密码:<input type="password" name="password"/><br/>
        验证码:<input type="text" name="checkCode"/><br/>
        <!--
            src="checkcodeServlet":
            表示打开login.html页面 加载img标签的src属性,向http://localhost:8080/checkcodeServlet获取图片展示
        -->
        <img id="imgId" src="checkcodeServlet" alt="" onclick="changeImg()"><br/>
        <input type="submit" value="登录"/>
    </form>

    <script>
        //点击img标签图片 就调用一次changeImg函数 向后台checkcodeServlet发送一次新的请求,获取一张新的验证码图片
        function changeImg() {
            console.log("切换验证码图片");
            //当点击验证码图片没有发起新的请求切换验证码的原因是  src=checkcodeServlet 新的路径和原来的路径一致,导致浏览器以外你没有发起新的请求,依然使用原来的图片
            //忽悠浏览器 点击一次验证码图片 就让浏览器发起一次新的请求 获取新的验证码展示【当请求地址不一样时,浏览器就会认为是一次新的请求】
            document.getElementById("imgId").setAttribute("src","checkcodeServlet?a="+new Date().getTime());
        }
    </script>
</center>
</body>
</html>
  • CodeServlet
@WebServlet("/checkcodeServlet")
public class CheckcodeServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //0.获取session对象【提前使用request获取session对象  不要在响应之后再去使用request对象】
        HttpSession session = request.getSession();

        //1.通过工具类 生成验证码图片  使用response将验证码图片写给客户端浏览器展示
        ServletOutputStream os = response.getOutputStream();
        String verityCode = CheckCodeUtil.outputVerifyImage(200, 50, os, 4);
        System.out.println("后台生成的验证码:verityCode = " + verityCode);

        //2.将生成的验证码保存在Session域对象中
        session.setAttribute("verityCode",verityCode);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
  • LoginServlet
/**
 * 登录实现步骤:
 *  0.处理请求响应中文乱码
 *  1.获取请求参数【用户名和密码】
 *  2.根据用户名和密码使用MyBatis查询数据库tb_user表 返回user对象
 *  3.判断user对象是否为null
 *  3.1:user==null:登录失败
 *  3.2:user!=null:登录成功
 */
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        SqlSession sqlSession = null;
        try {
            //*  0.处理请求响应中文乱码
            request.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");

            //*  1.获取请求参数【用户名和密码】
            Map<String, String[]> parameterMap = request.getParameterMap();
            User user = new User();
            BeanUtils.populate(user,parameterMap);

            /*==================使用验证码登录开始===================*/
            //1.获取用户输入的验证码
            String checkCode = parameterMap.get("checkCode")[0];

            //2.和后台生成的验证码进行比对
            //2.1:获取后台生成的验证码
            String verityCode = (String) request.getSession().getAttribute("verityCode");

            //用户输入的验证码为空  或者  用户输入的验证码和后台生成的验证码不一致
            if(checkCode==null || !checkCode.equalsIgnoreCase(verityCode)){
                // 3.1:不一致:响应用户 “验证码输入有误!”
                response.getWriter().print("验证码输入有误!");
                return;
            }
            // 3.2:一致:进行登录功能处理【省略】
            /*==================使用验证码登录结束===================*/

            //*  2.根据用户名和密码使用MyBatis查询数据库tb_user表 返回user对象
            //2.1:加载MyBatis配置文件
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            //2.2:获取SqlSessionFactory对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            //2.3:获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession();
            //2.4:获取dao接口代理对象
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            //2.5:调用方法
            User loginUser = userDao.select(user);

            //*  3.判断loginUser对象是否为null
            if(loginUser==null){
                //*  3.1:loginUser==null:登录失败
                response.getWriter().print("登录失败!");
            }else{
                //*  3.2:loginUser!=null:登录成功
                response.getWriter().print("登录成功!");
            }


        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().print("服务器异常!");
        }finally {
            if(sqlSession!=null){
                sqlSession.close();
            }
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

4.小结

  1. 验证码生成存储:
    1. 生成:直接使用工具类jar包生成
    2. 存储:要将生成的验证码存入到Session中
  2. 思路:
    1. 生成验证码
    2. 登录Servlet中比对用户输入的验证码和后台生成的验证码
    3. 根据用户名密码查询数据库
      1. user!=null:登录成功
      2. user==null:登录失败

总结

  1. 会话

    • 概念:浏览器和服务器的一次通话过程,称为会话
    • 会话产生:第一次打开浏览器,请求服务器并建立连接
    • 会话结束:指定服务器或浏览器两方有一方断开,会话结束
    • 会话技术:保存会话过程中产生的数据
      • cookie:保存数据在客户端浏览器
      • session:保存数据在服务器端
  2. Cookie

    • 概念:客户端的会话技术

    • 基本使用

      //1.创建Cookie对象
      Cookie cookie = new Cookie(String name,String value);
      //2.写入cookie到浏览器
      response.addCookie(cookie);
      //3.获取Cookie
      request.getCookies();
      cookie.getName();
      cookie.getValue();
      
    • 进阶使用

      //1.设置Cookie的有效时长
      cookie.setMaxAge();//-1:默认 会话级别    正整数:有效时间s   0:删除当前Cookie
      //2.设置Cookie的有效路径
      cookie.setPath();
      //3.Cookie存储中文和特殊字符
      URLEncoder.encode(value);   //编码
      URLDecoder.decode(value);   //解码
      
  3. Session

    • 概念:服务器端的会话技术

    • 基本使用

      //获取Session对象
      request.getSession();
      //存储数据
      setAttribute(String name,Object value);
      //获取数据
      getAttribute(String name);
      //移除数据
      removeAttribute(Sring name);
      
    • 进阶使用

      //1.设置Session的有效时间
      session.setMaxInactiveInterval(20); //单位是s
      //2.在tomcat的web.xml中设置Session有效时间  单位是minutes
      //3.设置Session手动失效
      session.invalidate();
      /*4.session持久化【了解】
      	1.手动持久化 将SessionId存入到Cookie,并设置有效时间
      	2.自动持久化  服务器完成 ,当服务器正常关闭,进行Session钝化,
      							当重启服务器,进行Session活化
      */
      
    1. JSP

      • 概念:jsp本质上就是一个Servlet

      • JSP执行原理:index.jsp-翻译->index_jsp.java-编译->class文件–>执行

      • jsp基本语法

        <% %>:java小脚本 用于编写java代码
        <%= %>:输出表达式  用于输出内容到页面
        <%! %>:声明  用于声明全局变量或方法
        <%-- --%>:jsp注释
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值