会话管理(Cookie、Session)

文章详细介绍了JavaEE中的Servlet、Filter和Listener三大组件,以及它们在web应用中的启动时机。重点讨论了HTTP协议的无状态特性,解释了如何通过Cookie和Session来管理会话。此外,还阐述了如何在Tomcat启动时执行初始化代码,包括使用Servlet的load-on-startup标签和ServletContextListener。最后,通过示例展示了如何使用request.getSession()方法来获取和操作Session。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

会话管理(Cookie、Session)

    1. javaee 的三大组件
    1. servlet的启动时机
    1. 从java application -> java web (servlet ,filter)原来程序“main”作为程序的入口。现在java web的主函数在哪里?
    • 3.1. 如果,我希望,tomcat启动的时候,就执行一些代码,该怎么做?
    1. 对http协议“无状态”特征的理解
    • 4.1. 具体来说,HTTP协议的无状态特征表现在以下几个方面:
    • 4.2. HTTP协议的无状态特征有以下优点和缺点:
    1. 还原http无状态
    • 5.1. Cookie 访问服务器之后服务器可以发送cookie给客户端,客户端默认就会保存这个cookie,下次自动发送!
    • 5.2. Session
    1. 解释request.getSession()方法
    • 6.1. 示例:

1. javaee 的三大组件

Servlet 大部分定义的业务对象
Filter 被调用的时机不同,运行方式不同(横切业务逻辑)
Listener 监听器

2. servlet的启动时机

servlet是单例的,创建的时机默认是:第一次访问的时候创建。
如果每个第一次访问都创建对象,慢。
可以配置servlet的启动时机
在web.xml中对Servlet进行配置

<load-on-startup>0</load-on-startup>

该Servlet就会在启动tomcat服务器的时候,自动地创建对象并且完成初始化工作

servlet可以通过配置创建对象。
Filter:自动地在tomcat启动的时候会创建并且初始化!

3. 从java application -> java web (servlet ,filter)原来程序“main”作为程序的入口。现在java web的主函数在哪里?

目前为止Servlet,Filter,是通过浏览器发起http访问被调用。

java web的主函数在tomcat启动。
tomcat启动,运行tomcat中定义的main,tomcat程序执行。
我们的java web项目,部署在tomcat中,被tomcat管理,为相应url访问,提供服务!

3.1. 如果,我希望,tomcat启动的时候,就执行一些代码,该怎么做?

做一些java web项目的“初始化”工作!

方式1:
人工地创建一个初始化的initServlet,不要提供服务,
利用0配置,
可以把初始化的语句定义在这个servlet中。

方式2:
能够让tomcat启动的,立即就执行
有没有什么方式实现!
ServletContextListener

定义:class InitListener implements ServletContextListener
把需要整个项目“初始化”的代码,定义在

public void contextInitialized(ServletContextEvent servletContextEvent)

方法中
在DD中配置:

<listener>
    <listener-class>com.woody.listener.InitListener</listener-class>
</listener>

tomcat服务器,启动的时候就自动调用本方法

在javaee中一共8种监听器,可以在“不同”场景中被调用。

ServletContextListener : 上下文监听
场景:tomcat启动时tomcat关闭时

还有与属性,会话相关的监听!

4. 对http协议“无状态”特征的理解

HTTP协议是一种无状态协议,也被称为无状态传输协议(Stateless Transfer Protocol)。这意味着每个HTTP请求都是相互独立的,服务器不会记住之前任何请求的状态或上下文信息。

4.1. 具体来说,HTTP协议的无状态特征表现在以下几个方面:

  1. 每个HTTP请求都是独立的:HTTP协议并不保留先前的请求或响应的状态信息。每个HTTP请求都是独立的,服务器无法判断该请求是否来自同一用户或是否与之前的请求相关。

  2. 无法跟踪会话状态:由于HTTP协议的无状态特性,服务器无法跟踪用户的会话状态。因此,Web应用程序必须使用其他机制来跟踪用户的状态,如使用Cookies、URL重写等方式。

  3. 无法保持长连接:由于HTTP协议的无状态特性,服务器在处理完一个HTTP请求后会立即关闭连接,无法保持长时间的连接,这样会增加了连接开销。

4.2. HTTP协议的无状态特征有以下优点和缺点:

优点:
简化服务器设计:服务器不必维护每个客户端的状态,这简化了服务器的设计和维护工作。
提高可伸缩性:由于服务器不需要为每个客户端维护状态,可以更轻松地处理大量的并发请求,提高了服务器的可伸缩性。

缺点:
不适合某些场景:在一些应用场景中,如在线支付、购物车等需要跟踪用户状态的应用中,HTTP协议的无状态特性会带来一些不便,需要采用其他机制来实现。
增加了一些额外的开销:为了解决HTTP协议的无状态特性带来的不便,Web应用程序需要采用一些额外的机制来跟踪用户状态,这会增加一些额外的开销和复杂性。

5. 还原http无状态

LoginServlet:验证的用户名密码,登入成功,应该把数据放在下一次可以访问到地方
AdminManageServlet: 从登入成功设置的“地方”获取数据,服务端就不需要再次验证。

思路:

  1. 浏览器应该存储一些数据
  2. 服务器应该有存储区别哪个用户的集合。

“记住密码”

  1. 浏览器中勾选“记住密码”复选框,点击登录
  2. 服务器验证用户名密码正确的情况下,发现用户需要“记住密码”。
  3. 服务器就会发回“记住密码”数据。
  4. 浏览器下次提交时,就会把用户名和密码数据,“自动”填入表单
  5. 因为用户名和密码已经填入,客户端只要点击登入。
  6. 就完成用户登入。

  1. 用户登入成功,没有构造“记住密码”或,用户登入不成功。
  2. 服务器就会发回不要“记住密码”数据。
  3. 用户需要再次添加用户名和密码!

5.1. Cookie 访问服务器之后服务器可以发送cookie给客户端,客户端默认就会保存这个cookie,下次自动发送!

  1. 服务端,创建cookie对象,添加到响应中,发回给客户端。
  2. 客户端接收到响应,把cookie的数据保存“浏览器”中。
  3. 下次访问同一个“网站”时(服务器的服务),会自动携带cookie数据
  4. 通过cookie的方式,实现了 “不同请求”之间数据“共享”。

 

DOM: document object model 文档对象模型(节点 元素,属性,文本)
BOM: browser object model 浏览器对象 (window, location, navigator, history, cookie)

5.2. Session

JsessionId = 1FC8720928E10F773699F28BAC174BCE
有没有一种“标记”能够,让服务器“知道”是哪个客户端。
通过这种“标记”把数据,保存在服务器。客户端只要提供这个标记就可以"jsessionId"

session保存在服务器。
通过getSession()方法
根据jsessionId查询session对象
如果找不到就创建对象,并且以键值对作为cookie返回给浏览器,还会在服务器申请空间存储该客户端的数据
如果找到,就直接可以获取操作数据的键值对对象
底层原来还是cookie ,只是用“特殊”的键值对“自动”帮助开发人员完成设置(addCookie, 查找)

session简化了对cookie的遍历操作!

6. 解释request.getSession()方法

request.getSession()方法用于获取当前请求对应的Session对象。Session对象是一种在Web应用中存储用户状态信息的机制,通过Session对象可以在多个请求之间共享数据。通常情况下,Session对象存储在服务器端,由服务器维护和管理,客户端通过Cookie或者URL重写等方式来进行Session的管理和维护。

实现原理流程:

  1. 当用户第一次访问Servlet时,Servlet容器会检查此用户是否已经有一个Session,如果没有则创建一个新的Session对象,同时给这个Session分配一个唯一的Session ID(通过使用一定算法生成),并将该Session对象与此次请求相关联。

  2. Servlet容器会将该Session ID 以cookie的形式发送给客户端(浏览器),并在浏览器本地存储该Session ID。

  3. 当客户端再次发送请求时,浏览器会将该Session ID 以cookie的形式附着在请求头中一起发送给服务器。

  4. Servlet容器接收到该请求后,根据请求头中包含的Session ID,利用该ID在服务器端查找已有的Session 对象。

  5. 如果查找成功,则表示客户端与服务器之前已经建立起连接(也就是说,客户端在请求头中携带的Session ID 与服务器中的Session ID 相匹配)。此时服务器就可以使用该Session对象,根据需要创建、读取、修改、删除Session中的数据,最后将响应数据写回客户端。

  6. 如果查找失败,则表示客户端与服务器之前还没有建立连接(也就是说,客户端在请求头中携带的Session ID 与服务器中的Session ID 不匹配)。此时Servlet容器会创建一个新的Session对象,并给该Session分配一个新的Session ID,以此来保证每一个Session对象的唯一性。然后将新的Session ID 以cookie的形式发送给客户端,并在服务器端与该ID相关联,最后将响应数据写回客户端。

综上所述,使用request.getSession()方法的实现原理就是:当客户端第一次请求Servlet时,Servlet容器会创建一个新的Session对象并为其分配一个唯一的Session ID,将该ID发送给客户端,并在服务器端与该ID相关联,从而实现对话的建立和记录。而当客户端再次请求服务器时,Servlet容器将在服务器端根据请求携带的Session ID 找到相应的Session对象,并根据需要进行数据的读取、修改、删除等操作。

需要注意的是,Session对象属于服务器端的对象,保存在服务器端的内存中或者磁盘中,而Session ID需要通过cookie或者其他方式发送给客户端,在客户端本地保存。因此,在使用Session时需要注意安全性问题,避免Session ID 被篡改或者伪造,导致安全风险。

6.1. 使用示例:

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

public class MyServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 获取Session对象
        HttpSession session = request.getSession();
        // 在Session对象中存储数据
        session.setAttribute("username", "Alice");
        session.setAttribute("age", 20);
        // 从Session对象中读取数据
        String username = (String) session.getAttribute("username");
        int age = (int) session.getAttribute("age");
        // 将数据返回给客户端
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<html><head><title>Session Demo</title></head>");
        out.println("<body>");
        out.println("<h1>Welcome, " + username + "!</h1>");
        out.println("<p>Your age is " + age + ".</p>");
        out.println("</body></html>");
    }
}
ody>");
        out.println("<h1>Welcome, " + username + "!</h1>");
        out.println("<p>Your age is " + age + ".</p>");
        out.println("</body></html>");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

奕の辰

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

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

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

打赏作者

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

抵扣说明:

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

余额充值