cookie 和 session的基本概念和java运用

第一章 会话技术

1、会话技术概述

目标: 解释说明会话技术的概念

步骤:

1、概念:为完成一个网络上的活动,用户打开浏览器多次请求服务器的资源,然后关闭浏览器。整个过程称之为一个会话;

2、生活中的网购场景演示:

小结:

1、会话概念:为完成一次网络上的活动,用户打开浏览器多次请求服务器,服务器给出多次响应。然后关闭服务器,这个过程称之为一次会话。
简而言之:会话就是由多次请求和响应组成的一次网络上的活动;

2、会话过程中要解决的问题

目标: 解释说明会话过程中要解决的问题

步骤:

1、多次请求和响应之间需要存储数据;

2、分析数据为什么不能存储在数据库中;

3、只能存在与BS交互双方中的任意一方;

实现:

1、多次请求和响应之间需要存储数据;

未登录情况下,往购物车中添加商品,关闭服务器后商品任然存在,说明数据被存储起来了。

在这里插入图片描述

2、数据为什么不能存储在数据库中;

1、用户未登录,无法标识购物车中商品所属用户,存储在数据库中不便于查询;
2、对数据库造成查询压力;

3、将数据存储在BS双方,且在多次请求和响应之间共享数据使用的技术:

Cookie技术:将数据存储在浏览器端;
Session技术:将数据存储在服务器端;
特点:能够在多次请求和响应之间共享。

在这里插入图片描述

小结:

1、会话期间需要解决的问题:数据存储
2、会话期间存储数据的技术:会话技术
	Cookie:将数据存储在浏览器端
	Session:将数据存储在服务器端
3、会话技术存储数据的特点:在多次请求和响应之间共享

第二章 Cookie技术

1、Cookie概述

目标:解释说明Cookie概念

步骤:

1、概念:Cookie指的是少量信息;

2、Cookie的产生:Cookie通常是由web服务器创建,发送给客户端(浏览器),并保存在客户端;

3、查看浏览器中的Cookie:打开Chrome浏览器,查看Cookie数据;

实现:

1、概念:Cookie指的是少量信息;

2、Cookie的产生:

1、创建:由web服务器创建,并发送给浏览器;
2、保存:保存在浏览器端(硬盘上);

3、查看浏览器中的Cookie:打开Chrome浏览器,查看Cookie数据;

在这里插入图片描述
谷歌浏览器将cookie保存到:C:\Users\用户名\AppData\Local\Google\Chrome\User Data\Default目录。

在这里插入图片描述

小结:

1、Cookie技术:在浏览器端保存小量信息的技术;
2、Cookie数据的产生:
	创建:web服务器创建,发送给浏览器
	保存:浏览器端存储(硬盘上)

2、Cookie的应用场景

	Cookie通常是将通过浏览器访问服务器的用户的信息存储在浏览器中用以标识用户。常见的应用场景有:1、自动登录;2、记住登录用户名和密码信息;

3、Cookie基本API

目标: 掌握Cookie的基本API

步骤:

第一步:解释说明Cookie的基本API;

创建:			  Cookie cookie = new Cookie(name,value);
获取name值:	 String name = cookie.getName();
获取value值:	 Strign value = cookie.getValue();
发送cookie:	  response.addCookie(cookie);
设置cookie的值: cookie.setValue(value);
获取所有cookie: Cookie[]  getCookies() = rquest.getCookies();

第二步:创建一个Servlet–CookieApiServlet演示以上方法;

第三步:观察浏览器中存储的Cookie信息和控制台中打印输出的Cookie信息。

实现:

第一步:创建一个Servlet–CookieApiServlet演示以上方法;

package com.heima.cookie;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author buguniao
 * @version v1.0
 * @date 2018/12/14 10:21
 * @description TODO
 **/
@WebServlet("/cookieApiServlet")
public class CookieApiServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //Cookie基本API的使用
        //1、创建Cookie
        Cookie cookie = new Cookie("name","张三");
        //2、发送Cookie
        response.addCookie(cookie);
        //3、获取Cookie的name值
        String name = cookie.getName();
        System.out.println(name);
        //4、获取Cookie的value值
        String value = cookie.getValue();
        System.out.println(value);
        //5、设置Cookie的value值4
        cookie.setValue("李四");
        //6、获取所有的Cookie
        Cookie[] cookies = request.getCookies();
        for (Cookie c : cookies) {
            System.out.println("name="+c.getName()+";value="+c.getValue());
        }
    }
}

第二步:查看浏览器中的Cookie
在这里插入图片描述

小结:

1、Cookie创建:
2、发送Cookie:
3、获取Cookie的name值和value值:
4、request中为什么会有Cookie:
5、获取Cookie的方法:

4、记住用户名和密码案例

目标: 使用Cookie技术记住用户名和密码案例

步骤:

1、前端:

【1】在登录页面上添加一个记住我复选框;

【2】填写登录信息,并提交表单数据到处理登录业务逻辑的Servlet;

2、后台:

【1】获取记住我 复选框的勾选状态,如果被勾选,则处理记住密码业务;

【2】记住密码业务处理:

第一步:用户登录成功之后,获取用户的用户名和密码;
第二步:创建Cookie对象,保存用户的用户名和密码信息;
第三步:将Cookie发送给浏览器保存;

3、前端:

【1】登录页面加载完成后,判断cookie中是否有用户名和密码信息,如果有,则将用户名和密码信息从浏览器中提出出来,动态更新到用户名和密码文本框中。

实现:

1、前端:

【1】在登录页面上添加一个记住我复选框;

在这里插入图片描述

【2】填写登录信息,并提交表单数据到处理登录业务逻辑的Servlet;

2、后台:

【1】获取记住我 复选框的勾选状态,如果被勾选,则处理记住密码业务;

【2】记住密码业务处理:

第一步:用户登录成功之后,获取用户的用户名和密码;
第二步:创建Cookie对象,保存用户的用户名和密码信息;
第三步:将Cookie发送给浏览器保存;
		//3、响应数据
        if (loginFlag) {
            //如果记住我复选框被勾选
            if ("remember-me".equals(rememberMe)) {
                //处理记住密码业务逻辑
                Cookie nameCookie = new Cookie("name", name);
                Cookie pwdCookie = new Cookie("password", password);
                //将Cookie发送给浏览器
                response.addCookie(nameCookie);
                response.addCookie(pwdCookie);
            }
            //登录成功  重定向到成功页面
            response.sendRedirect("/success.html");
        }

3、前端:

【1】登录页面加载完成后,判断cookie中是否有用户名和密码信息,如果有,则将用户名和密码信息从浏览器中提出出来,动态更新到用户名和密码文本框中。

<script>
    //页面加载完成之后 从浏览器中获取Cookie
    $(function () {
        var name = cookie.getCookie("name");
        var password = cookie.getCookie("password");
        //将用户名和密码更新到文本框中
        $("#inputName").val(name ? name : "");
        $("#inputPassword").val(password ? password : "");
        //恢复记住我复选框的状态
        if(name && password) {
            $("#rememberMe").prop("checked","checked");
        }
    });
</script>

【commons.js】

上述js代码中:cookie.getCookie()方法被封装在common.js中,使用前,先导入common.js文件。

var cookie = {
    getCookie: function (key) {
        return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
    }
};
4、观察案例的实现结果;

【1】访问:"/test/a";

在这里插入图片描述
【2】访问:"/test/a/b"
在这里插入图片描述
【3】访问:"/test"
在这里插入图片描述
小结:
xxxxxxxxxx 1、Cookie的有效路径:Cookie能够被访问到的路径;2、Cookie有效路径特点:能够在有效路径或其子路径下获取到Cookie;3、有效路径: 通常设置Cookie的有效路径为"/"或不设置;

5、Cookie的存活时间

目标: 解释说明Cookie的存活时间和存活时间的设置

步骤:

1、解释说明Cookie的分类:

会话级别的Cookie
持久型的Cookie

2、会话级别的Cookie:

概念:我们创建的Cookie对象默认是会话级别的Cookie,浏览器关闭后Cookie立即销毁;
演示:

3、持久型的Cookie:

持久型的Cookie:浏览器关闭后能够保存一段时间;

4、Cookie最大存活时间的设置:

void setMaxAge(int  seconds);

实现:

1、会话级别Cookie的创建及销毁演示:

第一步:打开上面实现的记住账号和密码案例;
第二步:关闭浏览器发现Cookie消失;

2、持久型Cookie的设置:设置Cookie的最大存活时间:

 //处理记住密码业务逻辑
Cookie nameCookie = new Cookie("name", name);
Cookie pwdCookie = new Cookie("password", password);

//设置Cookie的最大存活时间
nameCookie.setMaxAge(60*60);
pwdCookie.setMaxAge(60*60);

//将Cookie发送给浏览器
response.addCookie(nameCookie);
response.addCookie(pwdCookie);

小结:

1、Cookie分类:会话级别,持久型;
2、Cookie创建后:默认是会话级别的;
3、设置Cookie的最大存活时间:cookie.setMaxAge(int second);

6、Cookie的有效路径

目标: Cookie有效路径的设置及应用场景

步骤:

1、概念:Cookie有效路径–cookie允许被访问的路径。

2、特点:Cookie在其设置的有效路径和其子路径下能够被访问到;

3、案例演示:

第一步:创建Servlet--CookiePathServlet,设置一个Cookie("name","Hello Cookie!")的有效路径为"/web/a";
第二步:分别创建测试Servlet:CookieDemo1Servlet("/test/a"),CookieDemo2Servlet("/test/a/b"),CookieDemo3Servlet("/test");
第三步:分别在测试Servlet中获取Cookie("name","Hello Cookie!");

4、观察案例的实现结果;

实现:

1、概念:Cookie有效路径–cookie允许被访问的路径。

2、特点:Cookie在其设置的有效路径和其子路径下能够被访问到;

3、案例演示:

第一步:创建Servlet--CookiePathServlet,设置一个Cookie("name","Hello Cookie!")的有效路径为"/test/a";

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

        //创建Cookie,并设置有效路径为"/web/a"
        Cookie cookie = new Cookie("name", "HelloCookie!");
        //设置有效路径
        cookie.setPath("/test/a");
        //发送cookie
        response.addCookie(cookie);
    }

第二步:分别创建测试Servlet:CookieDemo1Servlet("/test/a"),CookieDemo2Servlet("/test/a/b"),CookieDemo3Servlet("/test");

第三步:分别在测试Servlet中获取Cookie(“name”,“HelloCookie!”);

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie[] cookies = request.getCookies();
        for (Cookie c : cookies) {
            if ("name".equals(c.getName())) {
                System.out.println("name="+c.getName()+";value="+c.getValue());
            }
        }
    }

4、观察案例的实现结果;

【1】访问:"/test/a";

在这里插入图片描述

【2】访问:"/test/a/b"

在这里插入图片描述

【3】访问:"/test"

在这里插入图片描述

小结:

1、Cookie的有效路径:Cookie能够被访问到的路径;
2、Cookie有效路径特点:能够在有效路径或其子路径下获取到Cookie;
3、有效路径:
	通常设置Cookie的有效路径为"/"或不设置;

7、Cookie删除

目标: 使用java代码删除Cookie

步骤:

  1. 创建与要删除的cookie同名的cookie,将其值设置成"";
  2. 将这个cookie的最大存活时间设置成0;
  3. 设置这个cookie的有效路径(与原cookie的有效路径一致);
  4. 将这个新的cookie响应给浏览器,置换原来的cookie;

实现:删除有效路径为"/test/a"的cookie;

在这里插入图片描述

第一步:创建一个Servlet–CookieDelServlet;

package com.heima.cookie;

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.io.IOException;

/**
 * @author buguniao
 * @version v1.0
 * @date 2018/12/14 11:26
 * @description TODO
 **/
@WebServlet("/cookieDelServlet")
public class CookieDelServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

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

第二步:在CookieDelServlet中创建一个与要删除的cookie同名的cookie,将其值设置成"";

第三步:将这个cookie的最大存活时间设置成0;

第四步:设置这个cookie的有效路径(与原cookie的有效路径一致);

第五步:将这个新的cookie响应给浏览器,置换原来的cookie;

在这里插入图片描述

第五步:访问DelCookieServlet,观察浏览器中这个Cookie是否还存在:

小结:

8、Cookie小结

- Cookie:服务器在客户端(浏览器)存储数据的技术;
- Cookie分类:
  - 会话级别:没有设置最大存活时间的cookie,浏览器关闭后消失;
  - 持久级别:设置了最大存活时间,浏览器关闭后不会消失;
- Cookie基本API:
  - 创建Cookie:Cookie c = new Cookie("name","zhangsan");
  - 获取name值:c.getName();
  - 获取value值:c.getValue();
  - 将cookie响应给浏览器:response.add(c);
  - 获取所有的cookie:Cookie[]  cookies = request.getCookies();
- Cookie的有效时间:
  - setMaxAge(int seconds):以秒为单位设置cookie的存活时间;
- Cookie的有效路径:
  - setPath(String path):设置cookie的有效路径,在这个路径及其子路径下有效;
- Cookie删除:
  - 客户端:
    - 会话级别的cookie,关闭浏览器后cookie立即消失;
    - 禁用cookie;
    - 手动清除cookie;
  - 服务端:
    - 通过Servlet,将原来的cookie置换;
- Cookie的优势及弊端:
  - 优势:
    - 为服务端标识用户提供依据;
    - 减轻了服务端数据存储的压力;
  - 弊端:
    - 数据存储在客户端不安全;
    - 存储的数据大小受限,一个cookie存储的数据最大为4K;

第三章 Session技术

1、Session概述

目标: 解释说明Session的概念及作用

步骤:

1、概念:Session是服务器为每个访问这个服务器的客户端用户创建的一个容器。

2、作用:这个容器中存储的数据能够在多个request之间实现共享。

3、特点:服务器为每个访问这个服务器的客户端用户创建的一个容器。

实现:

画图描述一下概念:

1、概念:Session是服务器为每个访问这个服务器的客户端用户创建的一个容器。

2、作用:这个容器中存储的数据能够在多个request之间实现共享。

3、特点:服务器为每个访问这个服务器的客户端用户创建的一个容器。

在这里插入图片描述

2、Session的应用场景

	凡是需要为每个用户在服务器端保存数据的,我们都可以使用Session来实现。Session最常见的应用场景:1、登录成功之后,将用户数据保存在session中;2、验证码校验过程中,将服务器端生成的验证码保存在session中;

目标:理解Session应用场景----登录成功之后,将用户数据保存在session中

步骤:

1、描述日常生活中的网购场景:添加购物车需要用户信息,下订单需要用户信息;

2、服务器获取用户信息的途径:用户登录;

3、需要处理的问题:登录成功之后,创建session对象,保存用户数据,在服务器内部共享;

小结:

1、描述日常生活中的网购场景:添加购物车需要用户信息,下订单需要用户信息;

2、服务器获取用户信息的途径:用户登录;

3、需要处理的问题:登录成功之后,创建session对象,保存用户数据,在服务器内部共享;

在这里插入图片描述

3、Session常用API(重要)

Session常用API包括:创建session,往session容器中存储数据,删除数据,获取数据

方法 使用示例 说明
request.getSession(); request.getSession(); 获取当前session
void setAttribute(String name,Object value) session.setAttribute(“loginUser”,user) 将一个对象与一个名称关联
之后存储到session中
Object getAttribute( String name) session.getAttribute(“loginUser”) 通过名称获取session
中的数据
void removeAttribute(String name) session.removeAttribute(“loginUser”) 根据指定名称删除
session中的数据
String sessionId = session.getId(); session.getId() 获取session的id
invalidate() ression.invalidate() 使当前session失效

目标:演示Session常用API

步骤:

1、创建Servlet–SessionAPIServlet,分别演示获取session,session存值,取值,移除值,获取id,销毁session方法;

2、Debug观察运行结果;

实现:

1、创建Servlet–SessionAPIServlet,分别演示获取session,session存值,取值,移除值,获取id,销毁session方法;

2、Debug观察运行结果;

package com.heima.session;

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;

/**
 * @author buguniao
 * @version v1.0
 * @date 2018/12/14 12:54
 * @description TODO
 **/
@WebServlet("/sessionAPIServlet")
public class SessionAPIServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

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

        //Session基本API演示
        //1、创建Session
        HttpSession session = request.getSession();

        //2、存值
        session.setAttribute("name", "张三");
         //3、取值
        String name = (String) session.getAttribute("name");
        System.out.println(name);
        //4、移除值
        session.removeAttribute("name");
        //5、获取session的id
        String sessionId = session.getId();
        System.out.println(sessionId);
        
        //6、销毁session
        session.invalidate();
    }
}

小结:

Session基本API:

在这里插入图片描述

4、Session标识用户的原理

目标:解释说明Session标识用户的原理

步骤:

小结:

1、Session标识用户的本质:Session通过服务器标识浏览器;
2、Session标识用户的实现:基于Cookie;
3、Session标识用户的流程:
	第一步:第一次创建session对象时,服务器把sessionid以Cookie的形式发送给浏览器;
	第二步:浏览器第二次访问服务器的时候,会携带这个Cookie;
	第三步:服务器根据浏览器上次存储在Cookie中的sessionId,查找到上次的Session;

5、Session的生命周期(了解即可)

5.1 Session创建

创建时机:第一次调用reqeust.getSession(); tomcat创建
使用session:域对象
		作用:存储数据   API: setAttribute(name,value)   getAttribute(name)   
		特点:在服务器端共享数据(多次请求和响应之间)
销毁:
		1、session手动销毁:session.invilidate();
		2、过期销毁:session默认存活时间--30min
		3、非正常关闭tomcat;     

当客户端浏览器第一次访问服务器时,服务器为每个浏览器创建不同的HttpSession对象。在服务器端使用request.getSession()方法来获得HttpSession对象

当第一次执行 request.getSession()是session对象就被创建了。后续的request.getSession()只能获取已创建的session。

在这里插入图片描述

5.2 Session使用

对下载案例进行修改,要求用户登录以后才能下载,没有登录,点击下载标签,让用户去登录页面进行登录

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="loginServlet" method="get">

    用户名:<input type="text" name="username"/> <br/>

    密码:<input type="text" name="password"/> <br/>

    <input type="submit" value="get提交" />
    </form>
</body>
</html>

LoginServlet.java

package cn.itheima.login;

import cn.itheima.domain.User;

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.io.IOException;

/**
 * Created by IntelliJ IDEA
 *
 * @author: admin
 * Date: 2018/8/23
 * Time: 11:56
 */
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = new User();
        user.setName(username);
        user.setPassword(password);
        //获取session  将用户信息保存在session中
        request.getSession().setAttribute("user",user);
        //去下载页面进行下载
        response.sendRedirect("download.html");
    }
}

对下载代码进行修改

DownloadServlet.java

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

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

        //获取session中user对象
        User user = (User) request.getSession().getAttribute("user");
        if (null == user){
            response.sendRedirect("login.html");
        }else {

            //获取文件名
            String filename = request.getParameter("filename");
            //获取文件路径
            String path = request.getServletContext().getRealPath("WEB-INF/" + filename);
            System.out.println(path);

            //获取文件类型
            String mimeType = request.getServletContext().getMimeType(filename);
            //将文件的类型告诉浏览器
            // response.setHeader("conten-type",mimeType);
            response.setContentType(mimeType);

            //告诉浏览器以附件的形式来展示文件
            response.setHeader("Content-Disposition", "attachment;filename=" + filename);


            //开启IO流进行下载
            File file = new File(path);

            if (file.exists()) {
                //如果文件存在  我们就开始下载
                //输入流
                FileInputStream in = new FileInputStream(file);
                //获取输出流
                ServletOutputStream outputStream = response.getOutputStream();

                //IO流拷贝
                int len = 0;
                byte[] arr = new byte[1024];

                while ((len = in.read(arr)) != -1) {
                    outputStream.write(arr, 0, len);
                }

                in.close();
                //response被销毁的时候被关闭
                // outputStream.close();

            }
        }
    }
}

5.3 Session销毁

方式一:时间超出了session的存活时间

session的默认存活时间是30分钟,在tomcat的全局配置文件web.xml中。(路径:tomcat/config/web.xml)



我们可以在web.xml中自己设置这个存活时间。我们设置的这个时间会覆盖原来的存活时间。

【注意】

注意:30分钟从什么时候开始计算?
从用户最后一次访问时间开始计算:
Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session"活跃(active)"了一次。

注意:开发中一般我们将session设置为30分钟,所以没有必要对session的存活时间进行设置。这个知识点了解就好了。

【案例】手动配置session的存活时间

将session-config这段配置复制到自己项目中的web.xml中。修改存活时间为1,测试生存时间。

【web.xml配置】

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
           version="3.1">
    <!--将session的存活时间设置成1-->
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>
</web-app>

提示:知识点了解即可,不需要掌握。

方式二:在Servlet中手动销毁

手动销毁session,调用的方法是:session.invalidate()方法;

package cn.itheima.session06;

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;

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

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建session
        HttpSession session1 = request.getSession();
        System.out.println("session1被创建了。session1="+session1);

        //手动销毁session
        session1.invalidate();
        System.out.println("session1被销毁了.......................");

        //再次获取session
        HttpSession session2 = request.getSession();
        System.out.println("session2="+session2);
    }
}

效果图:

在这里插入图片描述

方式三:服务器非正常关闭【了解】

如果正常关闭服务器,session的信息,会被序列化硬盘中,保存在tomcat的work\Catalina\localhost\web_day05,当tomcat下一次启动的时候,会把session加载回来。序列化的文件会被销毁。

5.4 浏览器关闭后,session持久化方案(重要)

通过上面的例子我们发现,浏览器关闭后,JSESSIONID就消失来,再次访问的时候又重新创建了一个新的session对象。这样,是比较消耗资源的。如何在浏览器关闭后,session能够继续存在呢?

答案:session之所以重新创建是因为,浏览器关闭后JESSIONID这个cookie消失了。所以,就不能够在标识这个session了。如果能够让cookie不消失(或者存活时间长点)就能够在很长一段时间内把这个标识发送给Servlet了。此时Servlet就能够找到之前创建的session对象了。

【实现方案】

   	1. 在Servlet中手动创建JESSIONID;
 	2. 手动设置JESSIONID的存活时间;
 	3. 将JESSIONID相应给浏览器;

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

【参考代码】

 package cn.itheima.sessionchi07;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

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

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //进行session持久化操作

        //保证cookie名称  JSESSIONID  获取session的id
        String id = request.getSession().getId();
        Cookie cookie = new Cookie("JSESSIONID",id);

        System.out.println("id = " + id);

        //对cookie进行持久化操作
        cookie.setMaxAge(60*30);
        //cookie响应回浏览器
        response.addCookie(cookie);
    }
}

【运行结果】

在这里插入图片描述

关闭浏览器再次访问:http://localhost:8080/chiServlet

在这里插入图片描述
总结:因为cookie被我们持久化了,所以,即使用户再次关闭浏览器,都会一直访问到刚才的session中。不会再次创建session而消耗内存了。

session持久化很重要,要求大家掌握

7、Session综合案例(重要)

验证码校验案例

7.1 验证码校验

【验证码】

验证码是由计算机给浏览器端生成的一张图片,这张图片上有扭曲变形的数字或文字。扭曲变形是为了防止光学识别。这个问题是由计算机生成评判,必须由人类才能解答。所以,就能够有效防止某个黑客对某一个特定注册用户用特定程序暴力破解。

【验证码校验】

在这里插入图片描述

【生成验证码】使用GUI技术

package com.heima.web;
package com.itheima.cookie.checkcode;

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;

/**
 * Created by tps on 2018/7/7.
 */
@WebServlet("/codeServlet")
public class CodeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // gui 生成图片
        // 1 高和宽
        int height = 30;
        int width = 60;
        String data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
        Random random = new Random();
        // 2 创建一个图片
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 3 获得画板
        Graphics g = image.getGraphics();
        // 4 填充一个矩形
        // * 设置颜色
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, width, height);
        g.setColor(Color.WHITE);
        g.fillRect(1, 1, width - 2, height - 2);
        // * 设置字体
        g.setFont(new Font("宋体", Font.BOLD | Font.ITALIC, 25));
        StringBuffer sb = new StringBuffer();
        // 5 写随机字
        for (int i = 0; i < 4; i++) {
            // 设置颜色--随机数
            g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));

            // 获得随机字
            int index = random.nextInt(data.length());
            String str = data.substring(index, index + 1);
            // 写入
            g.drawString(str, width / 6 * (i + 1), 20);
            sb.append(str);//  获取验证码数据
        }
        //  验证码保存到session中
        request.getSession().setAttribute("code",sb.toString());
        // 6 干扰线
        for (int i = 0; i < 3; i++) {
            // 设置颜色--随机数
            g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
            // 随机绘制先
            g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));
            // 随机点
            g.drawOval(random.nextInt(width), random.nextInt(height), 2, 2);
        }

        // end 将图片响应给浏览器

        ImageIO.write(image, "jpg", response.getOutputStream());
    }
}

【页面引入验证码】

在这里插入图片描述

 <form class="form-signin" action="/loginServlet" method="post">
        <div class="text-center">
          <h2 class="form-signin-heading">登录页面</h2>
        </div>
          <input type="text" name="name" id="inputName" class="form-control" placeholder="用户名" required autofocus>
          <input type="password" name="password" id="inputPassword" class="form-control" placeholder="密码" required>
        <div>
          <input type="text" name="checkCode" class="form-control" style="width: 184px;float: left;" placeholder="请输入验证码">
          <img style="width: 84px;margin-left: 29px;"  src="/checkCodeServlet" alt="">
        </div>
        <div class="checkbox" style="clear: both">
          <label>
            <input type="checkbox" id="rememberMe" name="rememberMe" value="remember-me"> 记住我
          </label>
        </div>
        <button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
      </form>

在这里插入图片描述

【验证码校验】
在这里插入图片描述
package com.heima.user.web;

import com.heima.user.bean.User;
import com.heima.user.service.UserService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 *@author buguniao
 */
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

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

        request.setCharacterEncoding("UTF-8");
        //1、获取请求数据
        String name = request.getParameter("name");
        String password = request.getParameter("password");
        String rememberMe = request.getParameter("rememberMe");
        //获取验证码
        String checkCode = request.getParameter("checkCode");

        //封装数据
        User user = new User();
        user.setName(name);
        user.setPassword(password);

        //验证码校验
        //1、获取session中的验证
        String serverCode = (String) request.getSession().getAttribute("code");
        if(!serverCode.equalsIgnoreCase(checkCode)){
            //验证码错误
            //登录失败  拼接login.html,并回显错误信息
            request.setAttribute("errorMsg", "验证码错误!");
            request.getRequestDispatcher("/loginErrorServlet").forward(request, response);
            return;
        }


        //2、处理数据:登录业务逻辑
        UserService userService = new UserService();
        boolean loginFlag = userService.login(user);


        //3、响应数据
        if (loginFlag) {
            //如果记住我复选框被勾选
            if ("remember-me".equals(rememberMe)) {
                //处理记住密码业务逻辑
                Cookie nameCookie = new Cookie("name", name);
                Cookie pwdCookie = new Cookie("password", password);
                //将Cookie发送给浏览器
                response.addCookie(nameCookie);
                response.addCookie(pwdCookie);
            }
            //登录成功  重定向到成功页面
            response.sendRedirect("/success.html");
        } else {
            //登录失败  拼接login.html,并回显错误信息
            request.setAttribute("errorMsg", "用户名或密码错误!");
            request.getRequestDispatcher("/loginErrorServlet").forward(request, response);
        }
    }
}

效果:

在这里插入图片描述

【验证码优化】

点击图片后,更新验证码

【第一步】给图片添加点击事件

在这里插入图片描述

【第二步】点击事件触发后,发送请求更新图片验证码

在这里插入图片描述

8、Servlet作用域总结

  • ServletContext域:
    一个WEB应用(项目)对应一个ServletContext,这个对象中保存的数据正在整个WEB项目中都有效;
    • 创建:服务器启动的时候;
    • 销毁:服务器关闭或项目移除后;
  • HttpSession:
    一次会话给客户端(浏览器)创建一个session。这个对象中保存的数据,一次会话(多次请求)内数据有效;
    • 创建:服务器第一次调用getSession()的时候;
    • 销毁:
      • 服务器非正常关闭(正常关闭:Session被序列化);
      • Session过期了:默认存活时间30分钟;
      • 手动调用session的invalidate()方法;
  • HttpServletRequest:
    一次请求创建一个request。这个对象中保存的数据,一次请求(请求链)内数据有效;
    • 创建:客户端向服务器发送一次请求;
    • 销毁:服务器为这次请求做出响应之后,销毁request;

【API操作】操作三个作用域对象的API

  • 存储数据:setAttribute(name,value);
  • 获得数据:getAttribute(name);
  • 删除数据:removeAttribute(name);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值