Cookie&Session详细笔记

1️⃣ Cookie技术

1.1 Cookie对象

  1. 创建Cookie对象,用于存储会话数据
new Cookie(String name, String value)
  1. 修改cookie对象
void setPath(String url)
void setMaxAge(int expiry) 
void setValue(String newValue) 
  1. 把cookie数据发送给浏览器保存
response.addCookie(cookie);
  1. 浏览器带着cookie访问服务器,服务器接收cookie信息
request.getCookies();

1.2 Cookie技术原理

  1. 服务器创建Cookie对象,保存会话数据,把cookie数据发送给浏览器
response.addCookie(cookie); // (响应头:set-cookie: name=iacky)
  1. 浏览器获取cookie数据,保存在浏览器缓存区,然后在下次访问服务器时携带cookie数据
(请求头: cookie: name=chen)
  1. 服务器获取浏览器发送的cookie数据。
request.getCookies();

1.3 Cookie细节。

  1. cookie 的数据类型一定是字符串,如果要发送中文,必须先对中文进行URL加密才可以发送。
  2. setPath (path):修改cookie所在的有效路径。
  • 什么是有效路径?
    如果把该cookie 设置到某个有效路径下,然后当浏览器访问这个有效路径的时候,才会携带cookie数据给服务器。
  1. setMaxAge(整数):设置cookie 的有效时间
  • 正整数: 表示超过了正整数的数值的时间,cookie就会丢失! ! (cookie保存浏览器的缓存目录)单位:秒。
  • 负整数: 表示如果浏览器关闭了,cookie就会丢失! (cookie保存浏览器内存)
  • 0: 表示删除同名的cookie
  1. cookie可以有多个,但是浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个cookie的大小限制为4KB

1.4 模板代码

public class Cookiedemo1 extends HttpServlet {
    
    
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
    
    
        // 创建Cookie对象,保存会话数据
        // 如果发送中文,必须先使用URLEncoder进行加密
        String name = URLEncoder.encode("张三", "utf-8");
        Cookie c1 = new Cookie("name", name);
        Cookie c2 = new Cookie("email", "[email protected]");
        // 发送cookie
        response.addCookie(c1);
        response.addCookie(c2);
        // 浏览器下次访问获取已有的cookie
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
    
    
            for (Cookie cookie : cookies) {
    
    
                // cookie的名
                String cname = cookie.getName();
                // cookie的值
                String cvalue = cookie.getValue();
                // 解密
                cvalue = URLDecoder.decode(cvalue, "utf-8");
                System.out.println(cname + "=" + cvalue);
            }
        } else {
    
    
            System.out.println("没有cookie信息!");
        }
    }
}

1.5 Cookie小案例

在这里插入图片描述

2️⃣Session技术

概念:Session代表服务器与浏览器的一次会话过程,这个过程是连续的,也可以时断时续的。在Servlet中,session指的是HttpSession类的对象。

2.1session数据结构

在servlet/jsp中,容器是用何种数据结构来存储session相关的变量的呢?我们猜测一下,首先它必须被同步操作,因为在多线程环境下session是线程间共享的,而web服务器一般情况下都是多线程的(为了提高性能还会用到池技术);其次,这个数据结构必须容易操作,最好是传统的键值对的存取方式。

那么我们先具体到单个session对象,它除了存储自身的相关信息,比如id之外,tomcat的session还提供给程序员一个用以存储其他信息的接口(在类org.apache.catalina.session. StandardSession里)

public void setAttribute(String name, Object value, boolean notify)

在这里可以追踪到它到底使用了何种数据:

protected Map attributes = new ConcurrentHashMap();

这就很明确了,原来tomcat使用了一个 ConcurrentHashMap对象存储数据,它刚好满足了两点需求:同步与易操作性

那么tomcat又是用什么数据结构来存储所有的session对象呢?

  • 还是ConcurrentHashMap (在管理session的org.apache.catalina.session. ManagerBase类里)
protected Map<String, Session> sessions = new ConcurrentHashMap<String, Session>();

2.2 Session创建步骤/创建时间/删除时间/如何保持:

步骤:
当JSP页面没有显式禁止session的时候,在打开浏览器第一次请求该jsp的时候:

  1. 服务器会自动为其创建一个session,并赋予其一个sessionID
  2. 发送给客户端的浏览器。以后客户端接着请求本应用中其他资源的时候,会自动在请求头上添加:Cookie:JSESSIONID=客户端第一次拿到的session ID
  3. 服务器端在接到请求时候,就会收到session ID,并根据ID在内存中找到之前创建的session对象,提供给请求使用。这也是session使用的基本原理。

转载的更详细的步骤:

  1. 用户请求某jsp页面,该页面设置了session=“true”;

  2. Servlet/jsp容器将其翻译为servlet,并加载、执行该servlet;

  3. Servlet/jsp容器在封装HttpServletRequest对象时根据cookie或者url中是否存在jsessionid来决定是绑定当前的session到HttpRequest还是创建新的session对象(在请求解析阶段发现并记录jsessionid,在Request对象创建阶段将session绑定);

  4. 程序按需操作session,存取数据;

  5. 如果是新创建的session,在结果响应时,容器会加入Set-cookie头,以提醒浏览器要保持该会话(或者采用URL重写方式将新的链接呈现给用户)。

通过上面的叙述读者应该了解了session是何时创建的,这里再从servlet这个层面总结一下:当用户请求的servlet调用了getSession方法时,都会获取session,至于是否创建新的session取决于当前request是否已绑定session。当客户端在请求中加入了jsessionid标识而servlet容器根据此标识查找到了对应的session对象时,会将此session绑定到此次请求的request对象,客户端请求中不带jsessionid或者此jsessionid对应的session已过期失效时,session的绑定无法完成,此时必须创建新的session。同时发送Set-cookie头通知客户端开始保持新的会话。


创建时间:
一个常见的误解是以为session在有客户端访问时就被创建,然而事实是:

  1. 当用户请求的servlet调用了getSession方法时,都会获取session,至于是否创建新的session取决于当前request是否已绑定session。
  2. 当客户端在请求中加入了jsessionid标识而servlet容器根据此标识查找到了对应的session对象时,会将此session绑定到此次请求的request对象,客户端请求中不带jsessionid或者此jsessionid对应的session已过期失效时,session的绑定无法完成,此时必须创建新的session。同时发送Set-cookie头通知客户端开始保持新的会话。

删除时间:

Session的销毁有两种情况:超时和手动销毁。

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

  2. 程序调用HttpSession.invalidate()
    在这里插入图片描述

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


如何保持:
当首次创建了session后,客户端会在后续的请求中将session的标识符带到服务端,服务端程序只要在需要session的时候调用getSession,服务端就可以将对应的session绑定到当前请求,从而实现状态的保持。当然这需要客户端的支持,如果禁用了cookie而又不采用url重写的话,session是无法保持的。

重写url 在每次请求的url请求头中加入jsessionid, 即可保持连接

如果几次请求之间有一个servlet未调用getSession(或者干脆请求一个静态页面)会不会使得会话中断呢?这个不会发生的,因为客户端只会将合法的cookie值传送给服务端,至于服务端拿cookie做什么事它是不会关心的,当然也无法关心。Session建立之后,客户端会一直将session的标识符传送到服务器,无论请求的页面是动态的、静态的,甚至是一副图片。

2.3 Session使用步骤;

HttpSession 对象:

  1. 创建HttpSession对象,用于保存会话数据
session = request.getSession(); 创建或获取session对象。
  1. 修改HttpSession对象
void setMaxInactivelnterval(int interval)设置session对象的有效时间。
void invalidate()  手动销毁session对象
  1. 保存会话数据(作为域对象)
session.setAttribute("name",Object);   保存数据
session.getAttribute("name")       获取数据
session.removeAttribute("name")    删除数据。

2.4 模板代码

在这里插入图片描述

2.5 session原理

  • 问题:服务器怎么区分不同的浏览器会话?
  • 前提:可以从session对象取出数据必须是存放数据的session对象!! !

同一浏览器中打开和不同浏览器中打开相同页面能否搜索到session结果如下:

  1. 浏览器1-窗口1(001):
//1 创建HttpSession对象
HttpSession session = request.getSession()
//2 保存会话数据。
session.setAttribute("name"," jacky");
  1. 浏览器1-窗口2(001): 可以得到
//1 创建HttpSession对象
HttpSession session = request.getSession()
//2 保存会话数据。
session.setAttribute("name"," jacky");
  1. 浏览器2: 不可以得到
//1 创建HttpSession对象
HttpSession session = request.getSession()
//2 保存会话数据。
session.setAttribute("name"," jacky");
  1. 新的浏览器1(没有标记或者不是001): 不可以得到
//1 创建HttpSession对象
HttpSession session = request.getSession()
//2 保存会话数据。
session.setAttribute("name"," jacky");

2.6 session细节

  1. setMaxinactivelnterval(秒数):设置session对象的有效时间,
  • 问题:session在什么销毁?
  • 注意:不是浏览器关闭,session对象就销毁!!!
  • 默认情况:等待30分钟空闲时间,session对象才会销毁。
<!--设置全局的session对象的过期时间(分钟)-->
<session-config>
	<session-timeout>1</session-timeout>
</session-config>
  1. JSESSIONID不会随着浏览器关闭而消失
/*设置JSESSIONID的时间,不会随着浏览器关闭而丢失!*/ 
Cookie c = new Cookie ("JSESSIONTD",session.getId());
c.setMaxAge (1*30*24*60*60) ;  //1个月
response.addCookie(c); 
  1. 直接手动销毁sessino对象v
invalidate( ); 
  1. 创建或得到session对象
创建或得到session对象,查询session对象
request.getSession() / request.getSession(true)
如果没有sessino对象,则创建新的session对象
request.getSession(false)
得到session对象,查询session对象,如果没有session对象,直接返回null

2.7 session原理

此行代码内部包括以下六个步骤

 HttpSession session = request.getSession();
  • 服务器创建Session对象,服务器会给这个session对象分配一个唯一的标记JSESSIONID
  • 把JSESSIONID作为Cookie发送给浏览器
  • 浏览器得到JSESSIONID保存下来,在下次访间时携带这个JSESSIONID去访问服务器
  • 服务器得到JSESSIONID,在服务器内存中搜索是否存在指定JSSESSINOID的 session对象
    • 如果找到,则返回这个session对象
    • 如果找不到,可能直接返回null,或者再创建新的session对象。

3️⃣Cookie和Session的异同优劣

cookie和session都属于servlet包下的子包

3.1 特点

Cookie特点:

  1. 会话数据放在浏览器端
  2. 数据类型只能string,而且有大小限制的,相对数据存放不安全

Session特点:

  1. 会话数据放在服务器端(服务器内存),占用服务器资源
  2. 数据类型任意类型,没有大小限制的
  3. 相对安全

3.2 存储位置

cookie:浏览器
在这里插入图片描述
session:服务器
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_40597409/article/details/113685337