首页 > 其他分享 >三个域对象->Request域、Session域、Application域

三个域对象->Request域、Session域、Application域

时间:2025-01-04 13:00:30浏览次数:3  
标签:session SpringMVC request ModelMap Request Application Session import ModelAndVi

Servlet中的三个域对象

请求域:request 会话域:session 应用域:application 三个域都有以下三个方法:

// 向域中存储数据
void setAttribute(String name, Object obj);
​
// 从域中读取数据
Object getAttribute(String name);
​
// 删除域中的数据
void removeAttribute(String name);

主要是通过:setAttribute + getAttribute方法来完成在域中数据的传递和共享。

request

接口名:HttpServletRequest 简称:request request对象代表了一次请求。一次请求一个request。 使用请求域的业务场景:在A资源中通过转发的方式跳转到B资源,因为是转发,因此从A到B是一次请求,如果想让A资源和B资源共享同一个数据,可以将数据存储到request域中。

session

接口名:HttpSession 简称:session session对象代表了一次会话。从打开浏览器开始访问,到最终浏览器关闭,这是一次完整的会话。每个会话session对象都对应一个JSESSIONID,而JSESSIONID生成后以cookie的方式存储在浏览器客户端。浏览器关闭,JSESSIONID失效,会话结束。

使用会话域的业务场景:

  1. 在A资源中通过重定向的方式跳转到B资源,因为是重定向,因此从A到B是两次请求,如果想让A资源和B资源共享同一个数据,可以将数据存储到session域中。

  2. 登录成功后保存用户的登录状态。

application

接口名:ServletContext 简称:application application对象代表了整个web应用,服务器启动时创建,服务器关闭时销毁。对于一个web应用来说,application对象只有一个。 使用应用域的业务场景:记录网站的在线人数。

request域对象

在SpringMVC中,在request域中共享数据有以下几种方式:

  1. 使用原生Servlet API方式。

  2. 使用Model接口。

  3. 使用Map接口。

  4. 使用ModelMap类。

  5. 使用ModelAndView类。

使用原生Servlet API方式

在Controller的方法上使用HttpServletRequest:

package com.powernode.springmvc.controller;
​
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
​
@Controller
public class RequestScopeTestController {
​
    @RequestMapping("/testServletAPI")
    public String testServletAPI(HttpServletRequest request){
        // 向request域中存储数据
        request.setAttribute("testRequestScope", "在SpringMVC中使用原生Servlet API实现request域数据共享");
        return "view";
    }
}

页面:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>view</title>
</head>
<body>
<div th:text="${testRequestScope}"></div>
</body>
</html>

超链接:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>index</title>
</head>
<body>
<h1>Index Page</h1>
<a th:href="@{/testServletAPI}">在SpringMVC中使用原生Servlet API实现request域数据共享</a><br>
</body>
</html>

测试结果:

image.png

这种方式当然可以,用SpringMVC框架,不建议使用原生Servlet API。

使用Model接口

@RequestMapping("/testModel")
public String testModel(Model model){
    // 向request域中存储数据
    model.addAttribute("testRequestScope", "在SpringMVC中使用Model接口实现request域数据共享");
    return "view";
}

使用Map接口

@RequestMapping("/testMap")
public String testMap(Map<String, Object> map){
    // 向request域中存储数据
    map.put("testRequestScope", "在SpringMVC中使用Map接口实现request域数据共享");
    return "view";
}

使用ModelMap类

@RequestMapping("/testModelMap")
public String testModelMap(ModelMap modelMap){
    // 向request域中存储数据
    modelMap.addAttribute("testRequestScope", "在SpringMVC中使用ModelMap实现request域数据共享");
    return "view";
}

Model、Map、ModelMap的关系

可以在以上Model、Map、ModelMap的测试程序中将其输出,看看输出什么:

image.png

看不出来什么区别,从输出结果上可以看到都是一样的。 可以将其运行时类名输出:

image.png

通过输出结果可以看出,无论是Model、Map还是ModelMap,底层实例化的对象都是:BindingAwareModelMap。

可以查看BindingAwareModelMap的继承结构:

image.png

通过继承结构可以看出:BindingAwareModelMap继承了ModelMap,而ModelMap又实现了Map接口。 另外,请看以下源码:

image.png

可以看出ModelMap又实现了Model接口。因此表面上是采用了不同方式,底层本质上是相同的。 SpringMVC之所以提供了这些方式,目的就是方便程序员的使用,提供了多样化的方式,可见它的重要性。

使用ModelAndView类

在SpringMVC框架中为了更好的体现MVC架构模式,提供了一个类:ModelAndView。这个类的实例封装了Model和View。也就是说这个类既封装业务处理之后的数据,也体现了跳转到哪个视图。使用它也可以完成request域数据共享。

@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
    // 创建“模型与视图对象”
    ModelAndView modelAndView = new ModelAndView();
    // 绑定数据
    modelAndView.addObject("testRequestScope", "在SpringMVC中使用ModelAndView实现request域数据共享");
    // 绑定视图
    modelAndView.setViewName("view");
    // 返回
    return modelAndView;
}

这种方式需要注意的是:

  1. 方法的返回值类型不是String,而是ModelAndView对象。

  2. ModelAndView不是出现在方法的参数位置,而是在方法体中new的。

  3. 需要调用addObject向域中存储数据。

  4. 需要调用setViewName设置视图的名字。

ModelAndView源码分析

以上我们通过了五种方式完成了request域数据共享,包括:原生Servlet API,Model、Map、ModelMap、ModelAndView 其中后四种:Model、Map、ModelMap、ModelAndView。这四种方式在底层DispatcherServlet调用我们的Controller之后,返回的对象都是ModelAndView,这个可以通过源码进行分析。

在以上四种方式中,拿Model举例,添加断点进行调试:

image.png

启动服务器,发送请求,走到断点:

image.png

查看VM Stack信息:

image.png

查看DispatcherServlet的1089行,源码如下:

image.png

可以看到这里,无论你使用哪种方式,最终都要返回一个ModelAndView对象。

提醒:大家可以通过以下断点调试方式,采用一级一级返回,最终可以看到都会返回ModelAndView对象。

image.png

session域对象

在SpringMVC中使用session域共享数据,实现方式有多种,其中比较常见的两种方式:

  1. 使用原生Servlet API

  2. 使用SessionAttributes注解

使用原生Servlet API

package com.powernode.springmvc.controller;
​
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
​
@Controller
public class SessionScopeTestController {
​
    @RequestMapping("/testSessionScope1")
    public String testServletAPI(HttpSession session) {
        // 向会话域中存储数据
        session.setAttribute("testSessionScope1", "使用原生Servlet API实现session域共享数据");
        return "view";
    }
​
}

视图页面:

<div th:text="${session.testSessionScope1}"></div>

超链接:

<a th:href="@{/testSessionScope1}">在SpringMVC中使用原生Servlet API实现session域共享数据</a><br>

使用SessionAttributes注解

使用SessionAttributes注解标注Controller:

package com.powernode.springmvc.controller;
​
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
​
@Controller
@SessionAttributes(value = {"x", "y"})
public class SessionScopeTestController {
​
    @RequestMapping("/testSessionScope2")
    public String testSessionAttributes(ModelMap modelMap){
        // 向session域中存储数据
        modelMap.addAttribute("x", "我是埃克斯");
        modelMap.addAttribute("y", "我是歪");
​
        return "view";
    }
}

注意:SessionAttributes注解使用在Controller类上。标注了当key是 x 或者 y 时,数据将被存储到会话session中。如果没有 SessionAttributes注解,默认存储到request域中。

application域对象

在SpringMVC实现application域数据共享,最常见的方案就是直接使用Servlet API了:

package com.powernode.springmvc.controller;
​
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
​
@Controller
public class ApplicationScopeTestController {
​
    @RequestMapping("/testApplicationScope")
    public String testApplicationScope(HttpServletRequest request){
        
        // 获取ServletContext对象
        ServletContext application = request.getServletContext();
​
        // 向应用域中存储数据
        application.setAttribute("applicationScope", "我是应用域当中的一条数据");
​
        return "view";
    }
}

视图页面:

<div th:text="${application.applicationScope}"></div>

超链接:

<a th:href="@{/testApplicationScope}">在SpringMVC中使用ServletAPI实现application域共享数据</a><br>

标签:session,SpringMVC,request,ModelMap,Request,Application,Session,import,ModelAndVi
From: https://blog.csdn.net/m0_70042640/article/details/144928183

相关文章

  • 【PHP编程】PHP Session 设置
    “在Web开发中,Session管理是非常重要的一个环节。通过Session,我们可以跟踪用户的状态,存储用户特定的信息,以及执行其他与用户会话相关的操作。”PHP提供了强大的Session功能,使得开发者可以轻松地设置和管理Session。本篇文章将深入探讨如何在PHP中设置Session,并通过丰富的代码示......
  • 【Seed-Labs 2.0】Cross-Site Scripting (XSS) Attack Lab (Web Application: Elgg)
    Overview跨站脚本(XSS)是网络应用程序中常见的一种漏洞。攻击者可利用该漏洞向受害者的网络浏览器注入恶意代码(如JavaScript程序)。利用这些恶意代码,攻击者可以窃取受害者的凭证,如会话cookie。利用XSS漏洞可绕过浏览器为保护这些凭证而采用的访问控制策略(即同一来源......
  • @SpringBootApplication
    简介:‌SpringBootApplication‌是SpringBoot框架中的一个核心注解,用于简化SpringBoot应用程序的配置和启动。它是一个组合注解,包含了多个子注解,主要包括SpringBootConfiguration、EnableAutoConfiguration和ComponentScan。子注解:‌@SpringBootConfiguration‌:这个注解相......
  • 新窗口打开同样的站点会共用sessionStrorage吗?
    在前端开发中,关于新窗口打开同样的站点是否会共用sessionStorage的问题,答案是否定的。具体来说,原因如下:sessionStorage的定义与特性sessionStorage是WebStorageAPI的一部分,提供了一种在浏览器会话期间存储数据的机制。它允许你访问一个对应当前源的sessionStorage对象。与loca......
  • C# 中HttpWebRequest发起HTTP请求,如何设置才能达到最大并发和性能
    前言在C#中使用HttpWebRequest发起HTTP请求时,达到最大并发和性能可以从以下几个方面改进:1、ServicePointManager设置ServicePointManager类是一个静态类,它提供了用于管理HTTP连接的属性和方法。为了提升并发性能,你需要调整以下几个关键属性:DefaultConnectionLimit:默认情况......
  • AnnotationConfigApplicationContext流程看@Configuration,@ComponentScan,其它注解be
    目录AnnotationConfigApplicationContext测试代码手动注册第1个bean:LocalConfig手动注册第2个bean:LocalConfig2refresh方法执行前技巧refresh的postProcessBeanFactory方法refresh的invokeBeanFactoryPostProcessors(beanFactory);BeanDefinitionRegistry执行所有......
  • DefaultSqlSession 和 SqlSessionTemplate 的线程安全问题
    总结自:DefaultSqlSession和SqlSessionTemplate的线程安全问题、MyBatis与Spring整合时是如何解决SqlSession线程不安全的问题的DefaultSqlSession原因1:Connection本身是线程不安全的。如果多个线程获取到同一个Connection进行数据库操作,一个线程正在更新数据,而另......
  • Object.freeze冻结属性和v-if结合requestAnimationFrame分帧渲染解决白屏
    计算100W条数据的长度造成2s延迟<template><div><h1>数据总长度{{arrList.length}}</h1></div></template><script>exportdefault{data(){return{arrList:[]}},created(){cons......
  • @SpringBootApplication之scanBasePackages
    @SpringBootApplication(scanBasePackages={"${yudao.info.base-package}.server","${yudao.info.base-package}.module"})这句话什么意思?让我解释一下这个注解的含义:`@SpringBootApplication(scanBasePackages={...})`是SpringBoot的核心注解,它有以下几个要点:1.......
  • 2024-12-06《WebApplication配置》
    WebApplication是用于配置HTTP管道和路由的web应用程序,接来下我将一一拆解它的组成。//////ThewebapplicationusedtoconfiguretheHTTPpipeline,androutes.///[DebuggerDisplay("{DebuggerToString(),nq}")][DebuggerTypeProxy(typeof(WebApplication.WebApplicatio......