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

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

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

  • 控制器中设置属性:

    java 复制代码
    @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对象访问

在我们的项目中:

html 复制代码
<!-- 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)
  1. 再找会话域(sessionScope)
  • 最后找应用域(applicationScope)

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

这就是为什么:

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

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

jsp页面有几种域

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

  • 页面域 (Page Scope)

    html 复制代码
       // 存值
    
       <%pageContext.setAttribute("name", "value");%>
    
       // 取值
    
       ${pageScope.name}
    • 作用范围:仅在当前页面有效
  • 生命周期:当前页面的处理完成之前
  • 适用场景:只在当前页面使用的数据
  • 访问对象:pageContext
  • 请求域 (Request Scope)

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

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

    html 复制代码
       // 存值
    
       <%application.setAttribute("appConfig", config);%>
    
       // 取值
    
       ${applicationScope.appConfig}
    • 作用范围:整个Web应用有效
  • 生命周期:从服务器启动到服务器关闭
  • 适用场景:所有用户共享的数据(如系统配置)
  • 访问对象:application

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

  1. 请求域:用于页面显示数据
java 复制代码
// 控制器中

@GetMapping("/list")

public String list(Model model) {

    model.addAttribute("contentPage", "event/list");  // 存入请求域

    return "layout/base";

}

<!-- JSP中 -->

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

  • 会话域:用于用户登录状态

    java 复制代码
    // 控制器中
    
    @PostMapping("/login")
    
    public Result<User> login(String username, String password, HttpSession session) {
    
        // ... 登录验证 ...
    
        session.setAttribute("loginUser", user);  // 存入会话域
    
    }
    html 复制代码
    jsp<!-- JSP中 --><c:if test="${not empty sessionScope.loginUser}"> // 从会话域获取 <span>欢迎,${sessionScope.loginUser.username}</span></c:if>

数据查找顺序:

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

选择使用哪个域的原则:

  • 能用小范围的就不用大范围的
  • 根据数据的生命周期选择合适的域
  • 考虑性能影响(作用域越大,占用资源越多)
相关推荐
DianSan_ERP10 天前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet
小道仙9710 天前
jenkins对接、jenkins-rest
java·servlet·jenkins·jenkins-rest
vx_Biye_Design11 天前
【关注可免费领取源码】云计算及其应用网络教学系统--毕设附源码35183
java·spring·spring cloud·servlet·eclipse·云计算·课程设计
啊哈哈哈哈哈啊哈哈13 天前
Spring MVC 项目结构学习笔记
java·spring boot·spring·servlet·maven
百锦再14 天前
Jenkins 全面精通指南:从入门到脚本大师
运维·后端·python·servlet·django·flask·jenkins
隔壁老王的代码14 天前
Jenkins的流水线详解
运维·servlet·jenkins
衍生星球14 天前
【JSP程序设计】Servlet对象 — page对象
java·开发语言·servlet·jsp·jsp程序设计
二哈喇子!14 天前
Servlet 开发技术
servlet
vx-Biye_Design14 天前
servlet家政公司管理系统-计算机毕业设计源码01438
java·vue.js·spring·servlet·tomcat·maven·mybatis
云和数据.ChenGuang14 天前
jenkins安装需要多少版本的jdk
java·servlet·jenkins