会话技术

151 阅读10分钟

一、Cookie

1.Cookie概念

Cookie:客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问。

2.Cookie的工作流程

image.png

服务端提供了两个Servlet,分别是ServletA和ServletB
浏览器发送HTTP请求1给服务端,服务端ServletA接收请求并进行业务处理
服务端ServletA在处理的过程中可以创建一个Cookie对象并将name=zs的数据存入Cookie
服务端ServletA在响应数据的时候,会把Cookie对象响应给浏览器
浏览器接收到响应数据,会把Cookie对象中的数据存储在浏览器内存中,此时浏览器和服务端就建立了一次会话
在同一次会话中浏览器再次发送HTTP请求2给服务端ServletB,浏览器会携带Cookie对象中的所有数据
ServletB接收到请求和数据后,就可以获取到存储在Cookie对象中的数据,这样同一个会话中的多次请求之间就实现了数据共享

3.Cookie的基本使用

  1. 发送Cookie

    1. 创建Cookie对象,并设置数据
        Cookie cookie = new Cookie("key","value");
    2. 发送Cookie到客户端:使用response对象
        response.addCookie(cookie);
    
  2. 获取Cookie

    1. 获取客户端携带的所有Cookie,使用request对象
        Cookie[] cookies = request.getCookies();
        遍历数组,获取每一个Cookie对象:for
        使用Cookie对象方法获取数据
            cookie.getName();
            cookie.getValue();
    

chrome浏览器查看Cookie的值

方式一:在谷歌浏览器右上方,打开设置。

image.png

方式二:打开开发者工具或者 使用快捷键F12 或者 Ctrl+Shift+I image.png

4.Cookie的原理分析

对于Cookie的实现原理是基于HTTP协议的,其中设计到HTTP协议中的两个请求头信息:

响应头: set-cookie
请求头: cookie

image.png

1.浏览器向A资源发送请求,A资源设置Cookie,响应给浏览器(Tomcat服务器都是基于HTTP协议来响应数据)
2.Tomcat发现后端要返回一个Cookie对象,Tomcat就会在响应头添加一行数据Set-Cookie:username=ls
3.浏览器获取到响应,从响应头获取Set-Cookie对应的值username=ls,将数据存储到浏览器。
4.浏览器再次发送请求给B资源,浏览器自动在请求头中添加Cookie:username=ls,发送给服务端B资源。
5.Request对象将请求头中Cookie对应的值封装为一个个Cookie对象,形成数组。
6.B资源通过Request对象获取Cookie[]后,从中获取到自己需要的数据。

5.Cookie的使用细节

1.Cookie的存活时间

1. 问题
    默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁

2. 解决
    如何解决浏览器一关闭,Cookie就被销毁的问题?

        setMaxAge(int seconds)方法 //设置Cookie存活时间
            参数值为:
            1.正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除
            2.负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie被销毁
            3.零:删除对应Cookie
3. 举例:
    //1.创建对象
    Cookie cookie = new Cookie("username","zs");
    //2.设置存活时间 ,1周 7天
    cookie.setMaxAge(60*60*24*7); 

2.Cookie如何存储中文

1.问题
    Cookie不能直接存储中文

2.解决
    在A资源采用URLEncoder.encode(),将编码后的值存入Cookie中
    在B资源获取Cookie中的值,获取的值为URL编码后的值,采用URLDecoder.decode()对编码的值进行URL解码。

3.举例:
    //发送Cookie
    //对中文进行URL编码
    value = URLEncoder.encode("李四", "UTF-8");
    //将编码后的值存入Cookie中
    Cookie cookie = new Cookie("username",value);
    //设置存活时间 ,1周 7天
    cookie.setMaxAge(60*60*24*7);
    //发送Cookie,response
    response.addCookie(cookie);
    
    
    //获取Cookie
    //1. 获取Cookie数组
    Cookie[] cookies = request.getCookies();
    //2. 遍历数组
    for (Cookie cookie : cookies) {
    //3. 获取数据
        String name = cookie.getName();
        if("username".equals(name)){
            String value = cookie.getValue();//获取的是URL编码后的值%E5%BC%A0%E4%B8%89
            //URL解码
            value = URLDecoder.decode(value,"UTF-8");
            System.out.println(name+":"+value);//value解码后为 李四
            break;
        }
    }

3.总结

Cookie的使用细节中,我们讲了Cookie的存活时间和存储中文:
    
    存活时间,需要掌握setMaxAage()API的使用
    存储中文,需要掌握URL编码和解码的使用

二、Session

1.Session概念

Session:服务端会话跟踪技术:将数据保存到服务端。

Session是存储在服务端而Cookie是存储在客户端
存储在客户端的数据容易被窃取和截获,存在很多不安全的因素
存储在服务端的数据相比于客户端来说就更安全

2.Session的工作流程

image.png

1.在服务端A获取一个Session对象,把数据存入其中
2.在服务端B获取相同的Session对象,从中获取数据。实现一次会话中多次请求之间的数据共享

3.Session的基本使用

在JavaEE中提供了HttpSession接口,来实现一次会话的多次请求之间数据共享功能。

1. 获取Session对象,使用的是request对象

    HttpSession session = request.getSession();

2. Session对象提供的功能:

    1.存储数据到 session 域中 :void setAttribute(String name, Object o)
    2.根据 key,获取值 : Object getAttribute(String name)
    3.根据 key,删除该键值对 : void removeAttribute(String name)
  1. 总结
1.Session的获取
    HttpSession session = request.getSession();
2.Session常用方法的使用
    void setAttribute(String name, Object o)
    Object getAttribute(String name)
    
注意:Session中可以存储的是一个Object类型的数据,也就是说Session中可以存储任意数据类型。

4.Session的原理分析

Session是基于Cookie实现的

image.png

结论:

1. 一次会话中Session对象是相同的。
2. Session实现的也是一次会话中的多次请求之间的数据共享。
(关闭浏览器,在打开浏览器,获取session,session对象就和上一次会话的session对象不同了)

1.问题

Session是如何保证在一次会话中获取的Session对象是同一个?

image.png

实现流程

1.资源1在第一次获取session 的时候,Session对象有一个唯一的标识,比如:id:2
2.资源1在session中存入其他数据并完成业务处理后,通过Tomcat服务器将响应返回给浏览器
3.Tomcat发现业务处理中使用了session对象,就会把session的唯一标识,id:2当作cookie,
    将 Set-Cookie:JESSIONID=2 添加到响应头中,返回给浏览器
    
4.浏览器收到响应,把响应头中的cookie数据存储到浏览器中。

5.浏览器在同一会话中,访问资源2的时候,
    将cookie中的数据按照cookie:JESSIONID=2的格式添加到请求头发送给服务器Tomcat.
    
6.资源2收到请求,从请求头读取cookie中JSESSIONID的值,然后寻找服务器中id:2的session对象,
    找到了,就直接返回该对象,没有就新建一个session对象。
    
7.关闭打开浏览器后,因为浏览器的cookie已被销毁,所以就没有JESSIONID的数据,服务端获取到的session就是一个全新的session对象

5.Session的使用细节

1.Session钝化与活化

服务器重启后,Session中的数据将会被销毁

1.问题
如何防止服务器重启后,session 中的数据不被销毁?

2.解决
Tomcat服务器在正常关闭和启动,session中的数据是可以被保存下来的。

    - 钝化:在服务器正常关闭后,Tomcat会自动将Session数据写入硬盘的文件中
        钝化的数据路径为:项目目录\target\tomcat\work\Tomcat\localhost\项目名称\SESSIONS.ser
    - 活化:再次启动服务器后,从文件中加载数据到Session中
        数据加载到Session中后,路径中的SESSIONS.ser文件会被删除掉

总结:

1. session数据存储在服务端,服务器重启后,session数据会被保存
2. 浏览器被关闭启动后,重新建立的连接就已经是一个全新的会话,获取的session数据也是一个新的对象
3. session的数据要想共享,浏览器不能关闭,所以session数据不能长期保存数据
4. cookie是存储在客户端,是可以长期保存

2.Session销毁

session的销毁会有两种方式:

1.默认情况下,无操作,30分钟自动销毁,这个失效时间可以配置,如果没有配置,默认是30分钟,默认值是在Tomcat的web.xml配置文件中写死的
    1.在项目的web.xml中配置
        <session-config>
            <session-timeout>100</session-timeout>
        </session-config>

2.调用Session对象的invalidate()进行销毁(该销毁方法一般会在用户退出的时候,需要将session销毁掉)
    1.在Servlet中设置。
        //获取Session对象
        HttpSession session = request.getSession();
        System.out.println(session);
        // 销毁
        session.invalidate();

三、请求与会话的区别

1.  会话:客户端与服务器交互的一个时间段。
2.  请求:在会话期间,可以发生N次请求,请求一次资源就发一个请求。
3.  当浏览器关闭后,会话不是立刻关闭,而是有一个超时等待时间,超过这个时间,会话就会关闭。

四、Cookie和Session的区别

1.相同之处

Cookie 和 Session 都是来完成一次会话内多次请求间数据共享的

2.Cookie和Session区别

存储位置:Cookie 是将数据存储在客户端,Session 将数据存储在服务端
安全性:Cookie不安全,Session安全
数据大小:Cookie最大3KB,Session无大小限制
存储时间:Cookie可以通过setMaxAge()长期存储,Session默认30分钟
服务器性能:Cookie不占服务器资源,Session占用服务器资源

3.Cookie和Session的应用场景分别是什么?

购物车:使用Cookie来存储
以登录用户的名称展示:使用Session来存储
记住我功能:使用Cookie来存储
验证码:使用session来存储

4.结论

Cookie是用来保证用户在未登录情况下的身份识别

Session是用来保存用户登录后的数据

五、记住我功能实现

实现流程:

因为记住我功能要实现的效果是,就算用户把浏览器关闭过几天再来访问也能自动填充,所以需要将登陆信息存入一个可以长久保存,并且能够在浏览器关闭重新启动后依然有效的地方,就是我们前面讲的Cookie.

1.记住我-设置Cookie

将用户名和密码写入Cookie中,并且持久化存储Cookie,下次访问浏览器会自动携带Cookie
在页面获取Cookie数据后,设置到用户名和密码框中
何时写入Cookie?
用户必须登陆成功后才需要写
用户必须在登录页面勾选了记住我的复选框
    (1)前端需要在发送请求和数据的时候,多携带一个用户是否勾选Remember的数据
    (2)LoginServlet获取到数据后,调用Service完成用户名和密码的判定
    (3)登录成功,并且用户在前端勾选了记住我,需要往Cookie中写入用户名和密码的数据,并设置Cookie存活时间
    (4)设置成功后,将数据响应给前端

2.记住我-获取Cookie

在页面获取Cookie中的数据,并把数据设置到登录页面的用户名和密码框中。

实现流程:

在页面可以使用EL表达式,${cookie.key.value}

key:指的是存储在cookie中的键名称