Cookie 与 Seesion的简单讲解(Java修仙体系结丹境)

Cookie

会话技术

一次会话:客户端与服务器建立连接,这就是一次会话,只要有一方断开(关闭),会话结束。同时,每次会话只对应一个浏览器,当有两个浏览器与服务器建立连接时,那么就相当有两个会话,不过会话的内容并不是共享的。服务器与浏览器1建立的会话内容,用浏览器2去接收会话消息是接收不到的。所以Cookie又称为客户端会话技术。

当服务器回写Cookie数据给客户端时,客户端会在本地记录一个Cookie文件,只要客户端不关闭,那么文件就不会销毁,关闭了,一次会话结束后,那么文件就会被销毁,但是我们也可以通过方法来延迟销毁时间。

简而言之,就是每个客户端请求服务器的时候,建立的会话都是不一样的,且会话内容不能共享使用。但是服务器可以接收所有的会话,Cookie会根据会话的不同处理,即使使用的资源是同一个。

浏览器每次发送请求时,就会根据域名进行检查,把该域名下的所有cookie发给服务器。

同样的,如果一个项目组中部署了多个Web项目,比如一个是 /test_1,一个是 /test_2,那么如果Cookie连接与 /test_1 建立了,再用 /test_2 去获取Cookie信息,是获取不到的。一次会话,对应的是 一个客户端和一个服务器,不能共享。但是我们可以通过一些方法来进行共享。

客户端第一次给服务器发送请求的时候,不会携带Cookie请求头。客户端回应的时候,会发送一个响应头,里面有Cookie属性

客户端第二次给服务器发送请求的时候,会携带一个Cookie请求头,客户端回应的时候,会一直有这个Cookie信息,直到有一方断开

实现步骤

// 创建一个新的Cookie,按照键值对来存储,不过必须都是字符串类型
Cookie cookie = new Cookie("key","value");

// 添加一个响应头,里面发送Cookie信息
reponse.addCookie(cookie);	// 这样浏览器就会接收到响应头,显示为 Cookie,请求头中显示 Set-Cookie
Cookie[] request.getCookies();	// 获取响应头中的Cookie信息

// 其中还有一个方法,可以用来更改Cookie中的内容
setValue(String newValue);

// 每一个Cookie都有两个方法,用来获取key与value	
String cookie.getKey();
String cookie.getValue();

关于Cookie的存活时间:一旦有一方关闭后,Cookie就会销毁,即使重新连接后,也获取不到之前的Cookie信息了,但是也有一个函数可以用来持久化存储

持久化存储,其实就是将Cookie信息保存在客户端本地硬盘上,下次访问的时候,浏览器自动调用。就好比我们登录一样,登录一次之后,后面好几天都可以不用在重新登录了。

cookie.setMaxAge(int 秒); // 正数:持久化存储,单位秒 | 负数:默认,断开连接销毁 | 0:直接删除当前调用的Cookie

关于多个项目与域名的共享问题

我们可以通过设置虚拟路径来扩大Cookie的共享范围,就比如上面的 /test_1 和 /test_2 两个Web项目,我们只要将Cookie的共享范围,设置成 / 就可以了。

setPath("虚拟目录路径"); // 想要其共享范围多大,就设置其目录范围

域名的共享问题,比如 tieba.badiu.com 和 news.baidu.com 他们的用户信息是一样的,但是部署的服务器肯定不一样,那么我们通过一个方法来进行设置

/tieba 属于二级域名 /baidu.com 属于一级域名,只要我们通过方法设置一级域名,他们之间的Cookie就可以共享

setDomain(String "一级域名"); // 像上面两个域名,只要设置 .baidu.com 这样他们之间的Cookie就可以共享了

需要注意的几个地方

特点: Cookie存储数据在客户端,且单个Cookie大小不得超过 4KB,每一个域名至多存储20个Cookie

作用: 用来存储少量的不敏感信息,不登陆的情况下对客户端进行身份识别,就如上面的登录信息一样,也可以用来存储 设置 信息等等。

最后,我们可以做一个小的案例

比如,有的网页在我们登录之后,会显示上一次的访问时间。

首先,客户端第一次访问服务器的时候,记录当前的时间
然后存放进Cookie中发送给客户端
并且设置其存储时间,一般为30天
当客户端第二次访问时,携带Cookie,服务器解析Cookie之后,获得上一次访问时间,回写数据到页面上
需要注意的是,分两个页面,显示的内容不一样。
其中在日期转换时有特殊字符不支持,需要用到函数进行编码解码

URLEncoder.encode("需要转码的对象","转换的编码");	// 这是进行编码
URLDecoder.decode("需要解码的对象","解码的编码");	// 这是进行解码,一般两者都为 utf-8

/** 以下是程序代码 **/

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    // 设置接收编码及响应编码
    req.setCharacterEncoding("utf-8");
    resp.setContentType("text/html;charset=utf-8");

    // 不管怎么样,都需要先设置一下当前的访问时间
    Date date = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH时_mm分ss秒SS毫秒");
    String visitTime = sdf.format(date);
    System.out.println(visitTime);

    boolean count = true;

    // 如果是第一次访问,先创建一个新的Cookie会写之后转发给 FirstTimeServlet 资源显示第一次访问内容
    Cookie[] cookies = req.getCookies();
    for (Cookie cookie : cookies) {
        // 如果是第二次访问,那么需要重新记录下当前的访问时间,并且写入Cookie
        if(cookie.getName().equals("lastTimeCookie")){
            count = false;
            cookie.setValue(visitTime);
            req.getRequestDispatcher("/secondTimeServlet").forward(req,resp);
        }
    }

    if(count){
        // 第一次访问,需要创建一个新的Cookie并且加入到响应头当中
        Cookie cook2 = new Cookie("lastTimeCookie",visitTime);
        resp.addCookie(cook2);
        req.getRequestDispatcher("/firstTimeServlet").forward(req,resp);
    }
}

Session

Seeion 是比 Cookie 更好的信息传输对象,Cookie用来存储一些不敏感的信息,而敏感的信息,一般用 Session 存储

关于底层的说明

当客户端第一次访问服务器获取 getSession() 的时候,会创建一个 SessionID = xxx; 的信息,并且开辟一块内存,存放Session,而信息则会写入在 Cookie 信息里面,所以 Session 是依赖于 Cookie 的,注意,这是第一次访问

然后服务器会立马在本地创建一个 Session 的文件,然后当服务器正常关闭后,一般存放的时间是30分钟,这是在Tomcat里面的初始值。注意,是关闭后。我们也可以手动修改时间,在后面会讲。

下面讲服务器和客户端假如有一方关闭后,又想下次建立会话时,数据不丢失的原理,方法在下面讲

客户端关闭,服务器开着:
服务器的本地是存放一个 Session 的文件,因为 Session 在传输中的存储是存放在Cookie信息中的,所以当客户端关闭后,Session 就会丢失了,当客户端再次请求的时候,服务器没有收到关于 SessionID 的Cookie信息会创建一个新的Session,覆盖掉原来的(服务器会将其当成一次新的会话)。关于解决的方法,我们在下面讲。

客户端开着,服务器关闭:
客户端开着,那么 Cookie 还是存在的,服务器关闭后,会完成一个 钝化 的过程:在服务器关闭前,会在本地会写入一个 Session 的文件,且存放时间为30分钟,这就是钝化。当服务器再次开启的时候,客户端发送请求给服务器,会携带服务器关闭之前的存放 SessionID 的Cookie信息,服务器开启后,将本地的Seesion文件转换为内存,这个重新加载的过程就是 活化。服务器校验SessionID,发现是一致的,就可以继续使用此SessionID的信息,数据没有丢失。注意,此操作只能用 Tomcat 文件夹里面部署的项目才会进行钝化的过程,IDEA里面是服务器开启后会删除之前的信息,然后重新创建一个,所以不能完成 钝化 和 活化。

到这里,已经将原理介绍的差不多了,下面讲一下 Session 和 Cookie 的不同之处。

Session 是存储在服务器端的,Cookie是存储在客户端,所以Session相对比较安全。
Session 可以存储任意类型、任意大小的信息,而Cookie的大小是有限制的
Session 相比于 requset ,其作用域更广,所以能够用于重定向中。

关于第三点:因为当有SessionID的客户端和服务器建立连接后,客户端进行了重定向,跳转到了其他页面之后,再回来。因为客户端会在本地写入一个临时文件,而服务器会存放在内存中。所以只要客户端和服务器端都没有关闭,那么之前的信息都还在。

下面就具体的说一下Seesion的一些方法

// 获取 Session 及 使用
Session session = request.getSession();	// 第一次访问就会创建,第二次访问就是获取
session.setAttribute("key",value);	// 可以是任意的数据类型
session.getAttribute("key");	// 根据 键 获取 值
session.removeAttribute("key");	// 根据 键 移除 值

手动销毁 Session
session.invalidate(); // 销毁内存和本地的Session

关于客户端关和服务器开的信息丢失的解决方法

我们可以手动创建一个 SessionID 存放在 Cookie 中,并且设置Cookie存活的最大时间,这样,只要服务器不关闭,客户端每次关闭开启后,只要Cookie没有过期,那么都会从本地 取出 Cookie存放SessionID的信息进行发送

Cookie cookie = new Cookie("SESSIONID",session.getID());	// ID的话,我们可以设置服务器给的,只不过是持久存储而已

cookie.setMaxAge(30 * 30 * 60);	// 存储30天
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烟雨红尘客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值