Servlet(三)会话跟踪技术

一、概述

会话技术:就是一次谈话,在Web浏览器服务器一次通信,那这次通信可以包含多次请求和多次响应

功能:在多次请求和多次响应间共享数据,记录信息确定用户身份

会话的结束标志:浏览器关闭,或者服务器关闭了代表这次会话就结束

分类:

(1)客户端会话技术:数据由客户端来保存

(2)服务端会话技术:数据由服务端来保存

二、客户端的会话技术--Cookie

(1)Cookie的由来(诞生)

     HTTP的特点:Web应用程序是使用HTTP协议传输数据的,而HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭再次交换数据需要建立新的连接,这就意味着服务器无法从连接上跟踪会话。

     需求引出:用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了,要跟踪该会话,必须引入一种机制。

     即:一个用户的所有请求操作都应该属于同一个会话,而另一个用户所有请求操作则应该属于另一个会话,二者不能混淆。例如:用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。

     说明:Cookie就是这样的一种机制,它就是为了弥补HTTP协议无状态的不足

     补充:在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话

     应用场景:我们在浏览器中,经常涉及到数据的交换,比如你登录邮箱登录账号等,会设置30天内记住我或者自动登录

     思考:那么它们是怎么记录信息的呢?

     提前解答:答案就是今天的主角Cookie了,Cookie是由HTTP服务器设置的,保存在浏览器中,但HTTP协议是一种无状态协议,在数据交换完毕后,服务器端和客户端的链接就会关闭,每次交换数据都需要建立新的链接。就像我们去超市买东西,没有积分卡的情况下,我们买完东西之后,超市没有我们的任何消费信息,但我们办了积分卡之后,超市就有了我们的消费信息。cookie就像是积分卡,可以保存积分,商品就是我们的信息,超市的系统就像服务器后台,http协议就是交易的过程。

(2)什么是Cookie

     Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。

(3)Cookie的原理图


     说明:由于HTTP是一种无状态的协议服务器单从网络连接上无从知道客户身份,怎么办呢?就给客户端颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证,这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。

     Cookie实际上是一小段的文本信息客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie(setCookie),客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态,服务器还可以根据需要修改Cookie的内容。

原理:
1.客户端请求一个资源,服务器做出响应时,会发送set-cookie头
2.客户端接收到响应,会将数据保存在客户端浏览器中
3.客户端再一次请求服务器时,会通过cookie头携带该数据。
4.服务端接收到请求,会来解析获取数据

(4)Cookie的分类

     cookie分为会话cookie持久cookie

      会话cookie:不设定它的生命周期,仅存活于当前的会话中(浏览器的缓存中);前面说了浏览器的开启到关闭就是一次会话,当关闭浏览器时,会话cookie就会跟随浏览器而销毁(HTTP的无状态所致)。当关闭一个页面时,不影响会话cookie的销毁。会话cookie就像我们没有办理积分卡时,单一的买卖过程,离开之后,信息则销毁。

     持久cookie:设定了它的生命周期持久化(序列化)到硬盘中。此时cookie像商品一样,有个保质期,关闭浏览器之后,它不会销毁,直到设定的过期时间。对于持久cookie,可以在同一个浏览器中传递数据比如你在打开一个淘宝页面登陆后,你在点开一个商品页面,依然是登录状态,即便你关闭了浏览器,再次开启浏览器,依然会是登录状态。这就是因为cookie自动将数据传送到服务器端,再反馈回来的结果。持久cookie就像是我们办理了一张积分卡,即便离开,信息一直保留,直到时间到期,信息销毁。

    体验:同一个浏览器中登陆某一个app后,不需要再登陆。

    补充:不同的浏览器采用不同的方式保存Cookie

(5)有关Cookie的几个方法

      setMaxAge(int second)

说明:正数:持久化到硬盘上;负数:默认值-1存在浏览器内存(缓存)中;0删除cookie

(6)测试

Servlet01--设置cookies的数据

package org.wzj.com;

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;
import java.net.URLEncoder;

@WebServlet(name = "Servlet01",value = "/test01")
public class Servlet01 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("设置Cookie数据!");
        //(1)设置Cookie---注意:Cookie的对象不是服务器创建的,需要开发者自己手动创建---键值对的形式
        //注意:Cookie是不支持中文字符的
        Cookie cookie1 = new Cookie("username", "Jane");
        Cookie cookie2 = new Cookie("id", URLEncoder.encode("国产零零七", "utf-8"));
        //(2)设置cookie的存活时间(会话结束后),
        cookie1.setMaxAge(80);
        cookie2.setMaxAge(80);
        //(3)服务器请求的时候,服务器做出响应(发送到浏览器端)--发送Cookie数据,注意抓包查看
        response.addCookie(cookie1);
        response.addCookie(cookie2);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

Servlet02--获取cookies的数据

package org.wzj.com;

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(name = "Servlet02",value = "/test02")
public class Servlet02 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //(1)从当前的会话中取出所有保存的cookie数据,打印到控制台(后台)
        Cookie[] cookies = request.getCookies();
        //(2)取出数据打印到控制台
        if(cookies!=null){
            for(Cookie cookie:cookies){
                //如何判断是不是我刚才存储的cookie数据
                String s = cookie.getName();//获取cookie的键
                if(s.equals("username")){
                    String value = cookie.getValue();//根据键找值
                    System.out.println(value);
                }
                if(s.equals("id")){
                    String value = cookie.getValue();
                    System.out.println(value);
                }
            }
        }

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

(7)Cookie需要注意的几个问题

        ①Cookie持久化的问题
        默认浏览器会将Cookie的数据包浏览器的内存当中,浏览器一关闭内存一释放,保存的数据就没了,那么我们肯定想要这个Cookie数据保存到硬盘上,浏览器即便关了在存活期,下次请求还是能够带回来的,服务器可以设置Cookie保存的位置以及周期。
        ②Cookie的都是字符串类型

        ③Cookie 不支持中文的解决办法

(8) Cookie的修改、删除

(9) Cookie的域

补充:Cookie机制定义了两种报头Set-Cookie报头Cookie报头,set-cookie存在于服务器响应的消息头中,而cookie则存在于客户端请求的消息头

三、服务器端会话技术--Session

(1) 将数据存储在服务器端

(2) session实现原理

       原理:用户请求时,服务器先创建session出来后,会把session的id号,以cookie的形式响应客户端;这样只要客户机的浏览器不关,再去访问服务器时,都会带着session的id号去,服务器发现客户机浏览器带session的id过来了,就会使用服务器内存中与之对应的session为之服务。

      具体:在打开浏览器第一次请求该jsp的时候,服务器会自动(理解--服务器对应的代码)为其创建一个session,并赋予其一个sessionID,发送给客户端的浏览器。以后客户端接着请求本应用中其它资源的时候,会自动在请求头上添加:Cookie:JSESSIONID=客户端第一次拿到的session ID,这样服务器端在接到请求时候,就会收到session ID,并根据ID在浏览器的内存中找到之前创建的session对象,提供给请求使用,这也是session使用的基本原理,必须搞懂这个。

      关键:session依赖于cookie存在;

(3)原理图


    解释: 假如浏览器A先访问Servlet1,这时候它创建了一个Session,Jsessionid号为110,然后Servlet1(服务器)将这个Jsessionid号以Cookie的方式返回给浏览器A,接着如果浏览器A继续访问Servlet2,那么这个请求会带上Cookie值: JSESSIONID=110,然后服务器根据浏览器A(携带)传递过来的ID号找到内存中的这个Session。 这时候假如浏览器B来访问Servlet1了,它的请求并没有带上JSESSIONID这个Cookie值,由于它也要使用Session,所以服务器会新创建一个Session,JSESSIONID号为119,并将这个ID号以Cookie的方式返回给浏览器B,之后的过程就同A了。

    补充:用户第一次请求,服务器调用 request.getSession()方法时,服务器会检查是否已经有对应的session,如果没有就在内存中创建一个session并返回给客户端该session的一个id以cookie保存,有的话就会在。

    注:其中Servlet1用于创建Session并添加属性Servlet2用于读取Session中的属性。 

说明:Session只针对当前的浏览器。

第一次请求的时候,服务器给予的响应信息(Set-Cookie)


第二次请求本应用其他资源的时候,会自动在请求头上添加Cookie:如下所示


(4)Session的细节

思考①浏览器关闭了,再次请求session一样吗?

答:不一样了

原因:浏览器关闭了(相当于会话结束),默认session仅存活于当前的会话中(如果没有将session持久化,保存的jsessionid没了),相当于创建了一个新的session

思考②服务器关闭了,再次请求session一样吗?

答:也不一样,会话结束,内存(缓存)释放了,但是虽然对象不一样了,但是session中存储的数据还是一样的(如何测试?)

5AA2703214C2400A3108A263817B2E6C:hehe

5AA2703214C2400A3108A263817B2F7G:hehe

他是如何识别是同一用户:是IP+端口+浏览器吗?

引出:钝化和活化

钝化:服务器正常关闭后,session对象会被写入(序列化)硬盘的文件中(测试时找其存储的位置)

活化服务器开启后,将文件还原(反序列化)为内存中的session对象(对应的文件消失)

注意:session包含的内容是实现java.io.Serializable接口的类实例,否则无法钝化和活化!!!

场景解析

       淘宝每年都会有定时抢购的活动,很多用户会提前登录等待长时间不进行操作,一直保存在内存中,而到达指定时刻,几十万用户并发访问,就可能会有几十万个session,  服务器被很多的session访问,内存不足,为了更好的运行,这时就需要进行对象的活化、钝化。:将一部分比较长时间没有变动的session从内存中写入到硬盘,让其在闲置的时候离开内存,将session信息保存至硬盘,等该session的用户重新使用的时候,那么该session文件就会自动从硬盘上加载到内存中,相当于会话没有中断,用户在整个过程中发觉不出来session又被调动的影响。

性能优化方案:用户信息不会丢失,并且最大限度的提高服务器(内存)的利用率。

场景2:服务器维护需要

(5) session的生命周期

创建:

request.getSession():
//会根据jsessionid值查找是否存在sesison对象,如果没找到则创建新的session

 销毁:

1)Session超时

超时:指的是连续一定时间服务器没有收到该Session所对应客户端的请求并且超过了服务器设置Session超时的最大时间

如何设置Session的有效时间(默认是30分钟),在server.xml中配置

			<session-config>
				<session-timeout>30</session-timeout>
			</session-config>

2)程序调用session.invalidate();----让session自杀!

3)服务器关闭或服务停止

思考③:如果客户端禁用了 cookie,session该如何自处?

说明:客户端禁用了cookie,session将不一样。

重写URL,将;jsessionid=731DED0DC4F0AA06CDBB815733D4043E拼接在地址栏

形如:http://localhost:8080/day09/s1;jsessionid=731DED0DC4F0AA06CDBB815733D4043E

说明:最好用Eclipse测试,IDEA中重启服务器会重新打开一个页面,所以看不到实验效果。

代码:

PrintWriter pw = response.getWriter();
HttpSession session = request.getSession();
String id = session.getId();
		
String href = "/day09/s1";
href = response.encodeRedirectURL(href);
System.out.println(href);
pw.write("<a href='"+href+"'>s1</a>");			

4.获取session:

getSession(boolean flag)
true:默认值,会根据jsessionid值查找是否存在sesison对象,如果没找到,则创建新的session

false:会根据jsessionid值查找是否存在sesison对象,如果没找到,则返回null

四、对比

客户端会话技术: Cookie 将数据保存客户端 服务器压力小,数据不安全。

服务端会话技术: 将数据保存在服务端,服务器压力大数据安全

相关链接:

分布式session:点击打开链接

session原理及实现集群session的方案原理:点击打开链接

Session之实现原理的深入讨论(禁用Cookie):点击打开链接

session:点击打开链接

大神:点击打开链接

应用场景(其中):点击打开链接

Cookie的原理:点击打开链接点击打开链接点击打开链接

会话跟踪技术:点击打开链接(URL),点击打开链接(SSL)


猜你喜欢

转载自blog.csdn.net/wzj_110/article/details/80614423
今日推荐