jsp中的四个域对象(Spring MVC)

server/2024/12/25 1:17:48/

在Spring MVC中,Model中的数据会被自动放入到请求域(Request Scope)中。也就是说,当我们在控制器中使用model.addAttribute()时,这些属性会被放入到HttpServletRequest对象的属性中。

让我们通过代码来详细解释:

  • 控制器中设置属性:
    @GetMapping("/list")
    public String list(Model model) {// 这里的数据会被放入请求域中model.addAttribute("contentPage", "event/list");return "layout/base";
    }

  • JSP中获取属性:

    <!-- 以下三种写法是等价的 -->

    <!-- 1. 直接使用EL表达式 -->

    ${contentPage}

    <!-- 2. 显式指定从请求域获取 -->

    ${requestScope.contentPage}

    <!-- 3. 使用JSP内置对象request -->

    <%=request.getAttribute("contentPage")%>

在JSP中,有四个主要的域对象:

  • 页面域(Page Scope):
  • 最小的作用范围
  • 仅在当前页面有效
  • 通过pageContext对象访问
  • 请求域(Request Scope):
  • 在一次请求中有效
  • Spring MVC的Model数据就是存在这里
  • 通过request对象访问
  • 会话域(Session Scope):
  • 在一次会话中有效
  • 用户登录信息通常存在这里
  • 通过session对象访问
  • 例如:${sessionScope.loginUser}
  • 应用域(Application Scope):
  • 在整个Web应用中有效
  • 所有用户共享
  • 通过application对象访问

在我们的项目中:
 

<!-- base.jsp --><!-- contentPage 从请求域获取 --><jsp:include page="/WEB-INF/views/${contentPage}.jsp"/><!-- 用户信息从会话域获取 --><c:if test="${not empty sessionScope.loginUser}"><span>欢迎,${sessionScope.loginUser.username}</span></c:if>

当使用EL表达式${contentPage}时,它会按照以下顺序查找属性:

  • 先找页面域(pageScope)
  • 再找请求域(requestScope)

3. 再找会话域(sessionScope)

  • 最后找应用域(applicationScope)

所以虽然我们在JSP中直接写${contentPage},但实际上它是从请求域中获取的,因为Spring MVC把Model中的数据都放在了请求域中。

这就是为什么:

  • 页面切换时contentPage的值会改变(因为是请求域,每次请求都是新的)
  • 而用户登录信息不会丢失(因为是会话域,会一直保持到用户退出登录)

这种域的概念是JSP中非常重要的一个概念,它们的作用范围不同,我们需要根据数据的特性选择合适的域来存储。

jsp页面有几种域

JSP页面有四种域(作用域/Scope),按照作用范围从小到大排序:

  • 页面域 (Page Scope)
       // 存值<%pageContext.setAttribute("name", "value");%>// 取值${pageScope.name}

    - 作用范围:仅在当前页面有效
  • 生命周期:当前页面的处理完成之前
  • 适用场景:只在当前页面使用的数据
  • 访问对象:pageContext
  • 请求域 (Request Scope)
       // 存值<%request.setAttribute("name", "value");%>// 或在控制器中model.addAttribute("name", "value");// 取值${requestScope.name}// 或简写为${name}

    - 作用范围:一次请求内有效
  • 生命周期:从请求开始到响应结束
  • 适用场景:在一次请求中传递的数据(如从控制器传到JSP的数据)
  • 访问对象:request
  • 会话域 (Session Scope)
       // 存值<%session.setAttribute("loginUser", user);%>// 或在控制器中session.setAttribute("loginUser", user);// 取值${sessionScope.loginUser}

  • 作用范围:一次会话内有效
  • 生命周期:从会话开始到会话结束(用户关闭浏览器或超时)
  • 适用场景:用户相关的数据(如登录信息)
  • 访问对象:session
  • 应用域 (Application Scope)
       // 存值<%application.setAttribute("appConfig", config);%>// 取值${applicationScope.appConfig}

    - 作用范围:整个Web应用有效
  • 生命周期:从服务器启动到服务器关闭
  • 适用场景:所有用户共享的数据(如系统配置)
  • 访问对象:application

在我们的项目中的实际应用:

1. 请求域:用于页面显示数据

// 控制器中@GetMapping("/list")public String list(Model model) {model.addAttribute("contentPage", "event/list");  // 存入请求域return "layout/base";}

<!-- JSP中 -->

<jsp:include page="/WEB-INF/views/${contentPage}.jsp"/>  // 从请求域获取

  • 会话域:用于用户登录状态
    // 控制器中@PostMapping("/login")public Result<User> login(String username, String password, HttpSession session) {// ... 登录验证 ...session.setAttribute("loginUser", user);  // 存入会话域}

    jsp<!-- JSP中 --><c:if test="${not empty sessionScope.loginUser}"> // 从会话域获取 <span>欢迎,${sessionScope.loginUser.username}</span></c:if>

数据查找顺序:

  • 当使用${name}这样的EL表达式时,会按照以下顺序查找:
  • pageScope
  • requestScope

3. sessionScope

  • applicationScope

选择使用哪个域的原则:

  • 能用小范围的就不用大范围的
  • 根据数据的生命周期选择合适的域
  • 考虑性能影响(作用域越大,占用资源越多)

http://www.ppmy.cn/server/152919.html

相关文章

springboot/ssm七彩云南文化旅游网站Java代码编写web在线旅游景点管理

springboot/ssm七彩云南文化旅游网站Java代码编写web在线旅游景点管理 基于springboot(可改ssm)htmlvue项目 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&…

【算法day20】回溯:子集与全排列问题

题目引用 非递减子序列全排列全排列II 1. 非递减子序列 给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xff0c;如出现两个整数相等&#x…

阿里云cdn稳定吗?

阿里云CDN&#xff08;内容分发网络&#xff09;是阿里云提供的一项全球加速服务&#xff0c;它的稳定性通常被认为是非常高的&#xff0c;尤其在国内市场。九河云给大家总结了阿里云CDN的稳定性情况&#xff1a; 1. 全球节点覆盖广泛 阿里云CDN在全球范围内拥有数百个加速节…

MongoDB常见面试题总结(上)

MongoDB 基础 MongoDB 是什么? MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统,由 C++ 编写的。MongoDB 提供了 面向文档 的存储方式,操作起来比较简单和容易,支持“无模式”的数据建模,可以存储比较复杂的数据类型,是一款非常流行的 文档类型数据库 。 …

RHCE-第七章:SELinux

一、selinux的说明 SELinux是Security-Enhanced Linux的缩写&#xff0c;意思是安全强化的linux。SELinux 主要由美国国家安全局&#xff08;NSA&#xff09;开发&#xff0c;当初开发的目的是为了避免资源的误用。系统资源都是通过程序进行访问的&#xff0c;如果将 /var/www…

【C/C++】推荐一个性能优良的错误码打印机制,已实测!

基于上1篇 switch与for的性能比较文章&#xff0c;若我们在开发一个较大型的系统架构&#xff0c;则错误码机制是必不可少的。 但是&#xff0c;基于灵活可扩展思想&#xff0c;我们的错误码是与日俱增的&#xff0c;所以&#xff0c;如何能不写很多switch-case语句&#xff0c…

【题解】—— LeetCode一周小结50

&#x1f31f;欢迎来到 我的博客 —— 探索技术的无限可能&#xff01; &#x1f31f;博客的简介&#xff08;文章目录&#xff09; 【题解】—— 每日一道题目栏 上接&#xff1a;【题解】—— LeetCode一周小结49 9.判断国际象棋棋盘中一个格子的颜色 题目链接&#xff1a;…

PostgreSQL 的历史

title: PostgreSQL 的历史 date: 2024/12/23 updated: 2024/12/23 author: cmdragon excerpt: PostgreSQL 是一款功能强大且广泛使用的开源关系型数据库管理系统。其历史可以追溯到1986年,当时由加州大学伯克利分校的一个研究团队开发。文章将深入探讨 PostgreSQL 的起源、…