会话技术知识点整理(Cookie和Session)

Posted 大忽悠爱忽悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了会话技术知识点整理(Cookie和Session)相关的知识,希望对你有一定的参考价值。

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

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

功能

在一次会话的范围内的多次请求间共享数据

方式

  1. 客户端会话技术: cookie
    2.服务器端会话技术; session

Cookie

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

基础使用步骤

在这里插入图片描述

修改servlet模板代码,方便编程

第一步:
在这里插入图片描述
第二步:
在这里插入图片描述

第三步:

在这里插入图片描述
第四步:
在这里插入图片描述


代码演示

CookieServlet1: ---->发送Cookie方

@WebServlet("/CookieServlet1")
public class CookieServlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     //1.创建Cookie对象
        Cookie c=new Cookie("msg","hello");
        //2.发送Cookie
        response.addCookie(c);
    }

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

CookieServlet1:接收Cookie方

@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       //获取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);
            }
        }
    }

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

在这里插入图片描述


Cookie实现原理

基于响应头set_cookie和请求头cookie实现

在这里插入图片描述
第一次访问服务器,响应头会返回 set-Cookie:
在这里插入图片描述

第二次访问,会带着上次请求返回的 Cookie 访问:
在这里插入图片描述
也需要注意,第一次 访问 Cookie1,接收到返回的 set-Cookie,第二次不是只有访问 cookie2 ,才能在响应头里看到Cookie,第二次访问哪个都会被携带,这里只是,我们在 Cookie2 这个页面设置了接收 Cookie 的数组,会被打印出来而已。


Cookie细节

一次发送多个Cookie

创建多个Cookie对象,使用response调用多次addcookie方法发送cookie即可

     //1.创建Cookie对象
        Cookie c=new Cookie("msg","hello");
        Cookie c1=new Cookie("msg","hello");
        //2.发送Cookie
        response.addCookie(c); 
        response.addCookie(c1);

Cookie在浏览器中保存的时间

默认情况下,浏览器被关闭后,cookie数据被销毁

Cookie的持久化存储

setMaxAge(int seconds)--->
  1. 正数: 将Cookie数据写到硬盘文件中,持久化存储. Cookie存活时间
  2. 负数:默认值
  3. 0:删除Cookie信息

Cookie能不能存储中文数据

  • tomcat 8版本之前,Cookie中不能直接存储中文数据
    需要将中文数据转码,一般采用URL编码(%E3)
  • tomcat 8版本之后,Cookie中支持中文数据
    特殊字符还是不支持,建议使用URL编码存储,URL编码解析,例如空格

Cookie共享问题

1 假设在一个tomcat服务器中,部署了多个web项目,那么这些web项目中cookien能不能共享?

  • 默认情况下cookie不能共享
setPath(String path): 设置Cookie的共享范围. 默认情况下,设置为当前的虚拟目录

如果要共享,可以将Cookie设置为"/"

/----->当前项目的根路径—>localhost/

注意: 以上方法是用来解决同一个服务器下,多个web项目的Cookie共享问题


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

setDomain(String path):如果设置一级域名相同,那么多个服务器之间Cookie可以共享

例如:

setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中的Cookie可以共享

Cookie的特点和作用

特点:

  1. Cookie存储数据在客户端浏览器
  2. 浏览器对于单个Cookie的大小由限制(4kb),以及对同一域名下的总Cookie数量也有限制(20)

作用:

  1. Cookie一般用于存储少量的不太敏感的数据
  2. 在不登录的情况下,完成服务器对客户端的身份识别

案例: 记住上一次访问时间

在这里插入图片描述

注意: cookie不支持特殊字符,因此需要采用URL编码存储,用URL解码来解析

代码加注释:

package com.example.Cookie1;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应消息体的数据格式以及编码
        response.setContentType("text/html;charset=utf-8");
        //判断是否有cookie的值为lastTime
        boolean flag=false;
        //获取所有Cookie
        Cookie[] cookies = request.getCookies();
        //遍历Cookie数组
        if(cookies!=null&&cookies.length>0)
        {
            for(Cookie c:cookies)
            {
               //获取cookie的名称
                String name = c.getName();
                //判断名称是否是lastTime
                if("lastTime".equals(name))
                {
                    //有该cookie,说明不是第一次访问
                    flag=true;//有lastTime的cookie
                    //响应数据
                    //获取cookie的value---->时间
                    String value = c.getValue();
                    System.out.println("解码前:"+value);
                    //URL: 解码
                    value= URLDecoder.decode(value, "utf-8");
                    System.out.println("解码后:"+value);

                    response.getWriter().write("<h1>欢迎回来,您上一次访问的时间为:"+value+"</h1>");

                    //设置Cookie的value
                    //获取当前时间的字符串,重新设置cookie的值,重新发送cookie
                    Date date = new Date();
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年mm月dd日 HH:mm:ss");
                    String format = simpleDateFormat.format(date);
                    
                    //URL编码
                    System.out.println("编码前:  "+format);
                   format=URLEncoder.encode(format,"utf-8");//
                    System.out.println("编码后:"+format);
                    //设置cookie的值
                    c.setValue(format);
                    //设置cookie的存活时间---一个月
                    c.setMaxAge(60*60*24*30);
                    //发送cookie
                    response.addCookie(c);

                       break;
                }
            }
        }
      if(cookies==null||cookies.length==0||flag==false)
        {
           //没有,说明是第一次访问
            //设置Cookie的value
            //获取当前时间的字符串,重新设置cookie的值,重新发送cookie
            Date date = new Date();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年mm月dd日 HH:mm:ss");
            String format = simpleDateFormat.format(date);
            Cookie c=new Cookie("lastTime",format);
            //URL编码
            System.out.println("编码前:  "+format);
            format=URLEncoder.encode(format,"utf-8");//
            System.out.println("编码后:"+format);
            //设置cookie的值
            c.setValue(format);
            //设置cookie的存活时间---一个月
            c.setMaxAge(60*60*24*30);
            //发送cookie
            response.addCookie(c);
            response.getWriter().write("<h1>欢迎首次访问</h1>");
        }
    }

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

在这里插入图片描述


Session

概念

服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。 HttpSession

一次会话的概念

一次会话,什么是一次会话呢?我举个例子:就我们现在上网,打开浏览器浏览网站当时开始到你关闭浏览器,就称之为一次会话;

HttpSession对象—共享数据

1 获取HttpSession对象

 request.getsession()

2 使用HttpSession对象

Object getAttribute(String name)
void setAttribute(String name,Object value)
void removeAttribute(String name)

代码演示:

Demo1Servlet :

@WebServlet("/SessionDemo1")
public class SessionDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         //使用session共享数据

        //1.获取session数据
        HttpSession session = request.getSession();
        //2.存储数据
        session.setAttribute("msg","大忽悠");
    }

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

Demo2Servlet:

@WebServlet("/SessionDemo2")
public class SessionDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         //1.获取session
        HttpSession session = request.getSession();
        //2.获取数据
        Object msg = session.getAttribute("msg");
        System.out.println(msg);
    }

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

在这里插入图片描述


Session原理

Session的实现是依赖与Cookie的

在这里插入图片描述


当客户端关闭后,服务器不关闭,两次获取session是否为同一个

默认情况下不是,因为客户端关闭后,一次会话就结束了.

如果需要相同,则可以创建Cookie,键为JSESSIONID,让Cookie持久化保存

代码演示:

         //1.获取session
        HttpSession session = request.getSession();
        Cookie c=new Cookie("JSESSIONID",session.getId());
        c.setMaxAge(60*60);
        response.addCookie(c);
        //2.获取数据
        Object msg = session.getAttribute("msg");
        System.out.println(msg);

客户端不关闭后,服务器关闭,两次获取session是否为同一个

不是同一个,但是要确保数据不丢失

1.session钝化: 在服务器正常关闭之前,将session对象系列化到硬盘上

2.session活化: 在服务器启动后,将session文件转化为内存中的session对象即可

tomcat服务器会自动完成钝化和活化过程,但是IDEA不会,因此一般将项目直接放到tmocat的webapps目录下


Session被销毁时机

服务器关闭时,session对象被销毁

session对象调用invalidate()来销毁自己

session默认失效时间为30分钟

我们可以对默认失效时间进行修改:
在这里插入图片描述
web.xml配置文件目录,大概500-600多行:
在这里插入图片描述


session特点

  1. session用于存储一次会话的多次请求的数据,存储在服务器端
  2. session可以存储任意类型,任意大小的数据

session与cookie的区别

  1. session存储数据在服务器端,cookie在客户端
  2. session没有数据大小限制,而cookie有
  3. session数据安全,cookie相对于不安全

验证码案例

1.案例需求

在这里插入图片描述

2.案例分析

在这里插入图片描述
在访问浏览器时,会有两个请求,因为验证码图片试一次单独的请求

完整代码

在这里插入图片描述
需要导入的jar包:
在这里插入图片描述

配置文件:

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///test1
username=root
password=xxxx
#初始化连接数量
initialSize=5
#最大连接数
maxActive=10
#最大等待时间
maxWait=3000

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>战地六游戏官网</title>

    <script>
        window.onload=function(){
        document.getElementById("img").onclick=function (){
            this.src="/ZhanDi/CheckCodeServlet?time="+new Date().getTime();
        }
        }
    </script>
    <style>
        div{
            color: red;
        }
    </style>
</head>
<body>
    <form action="/ZhanDi/LoginServlet" method="get">
         <table>
             <tr>
                 <th>用户名:</th>
                 <td><input type="text" placeholder="请输入用户名" name="username"></td>
             </tr>

             <tr>
                 <th>密码:</th>
                 <td><input type="password" placeholder="请输入密码" name="password"></td>
             </tr>

             <tr>
                 <th>验证码:</th>
                 <td><input type="text" placeholder="请输入验证码" name="checkcode"></td>
             </tr>

             <tr>
                 <td colspan="2"> <img id="img" src="/ZhanDi/CheckCodeServlet"></td>
             </tr>

             <tr>
                 <td colspan="2"> <input type="submit" value="登录"></td>
             </tr>
         </table>

    </form>
    <div><以上是关于会话技术知识点整理(Cookie和Session)的主要内容,如果未能解决你的问题,请参考以下文章

基础知识《十二》一篇文章理解Cookie和Session

Cookie&Session 知识点

计算机网络基础知识之Cookie与Session

Python爬虫知识点——Session与Cookie

会话技术: Cookie 和 Session

会话技术:cookie和session