三个域对象

一、Servlet中的三个域对象

  • 请求域:request
  • 会话域:session
  • 应用域:application

三个域都有以下三个方法:

// 向域中存储数据
void setAttribute(String name, Object obj);

// 从域中读取数据
Object getAttribute(String name);

// 删除域中的数据
void removeAttribute(String name);

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

1.1 request

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

1.2 session

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

使用会话域的业务场景:

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

1.3 application

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

二、request域对象

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

  1. 使用原生Servlet API方式。
  2. 使用Model接口。
  3. 使用Map接口。
  4. 使用ModelMap类。
  5. 使用ModelAndView类。

2.1 使用原生Servlet API方式

在Controller的方法上使用HttpServletRequest:

package com.liming.controller;

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author LiMing
 * @version 1.0
 * @description: TODO
 * @date 2024/4/11 10:40
 */
@Controller
public class RequestScopeTestController {

    @RequestMapping("/")
    public String toIndex(){
        return "index";
    }

    @RequestMapping("/testServletAPI")
    public String testServletAPI(HttpServletRequest request){
        // 向request域中存储数据
        request.setAttribute("testRequestScope","在SpringMVC中使用原生Servlet API实现request域数据共享");
        return "view";
    }

}

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>

index:

<!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>

测试结果:

在这里插入图片描述

在这里插入图片描述

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

2.2 使用Model接口

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

2.3 使用Map接口

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

2.4 使用ModelMap类

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

2.5 Model、Map、ModelMap的关系

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

在这里插入图片描述

看不出来什么区别,从输出结果上可以看到都是一样的。

可以将其运行时类名输出:

在这里插入图片描述

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

可以查看BindingAwareModelMap的继承结构:

在这里插入图片描述

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

在这里插入图片描述

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

2.6 使用ModelAndView类

在SpringMVC框架中为了更好的体现MVC架构模式,提供了一个类:ModelAndView。这个类的实例封装了ModelView。也就是说这个类既封装业务处理之后的数据,也体现了跳转到哪个视图。使用它也可以完成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设置视图的名字。

2.6.1 ModelAndView源码分析

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

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

在这里插入图片描述

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

在这里插入图片描述

查看VM Stack信息:

在这里插入图片描述

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

在这里插入图片描述

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

三、session域对象

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

  1. 使用原生Servlet API
  2. 使用SessionAttributes注解

3.1 使用原生Servlet API

package com.liming.controller;

import jakarta.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author LiMing
 * @version 1.0
 * @description: TODO
 * @date 2024/4/11 11:23
 */
@Controller
public class SessionScopeTestController {
    @RequestMapping("/testSessionScope1")
    public String testServletAPI(HttpSession session) {
        // 向会话域中存储数据
        session.setAttribute("testSessionScope1", "使用原生Servlet API实现session域共享数据");
        return "view";
    }
}

view:

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

index:

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

测试:

在这里插入图片描述

在这里插入图片描述

3.2 使用SessionAttributes注解

使用SessionAttributes注解标注Controller:

package com.liming.controller;

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;

/**
 * @author LiMing
 * @version 1.0
 * @description: TODO
 * @date 2024/4/11 11:23
 */
@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.liming.controller;

import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author LiMing
 * @version 1.0
 * @description: TODO
 * @date 2024/4/11 11:29
 */
@Controller
public class ApplicationScopeTestController {

    @RequestMapping("/testApplicationScope")
    public String testApplicationScope(HttpServletRequest request){

        // 获取ServletContext对象
        ServletContext application = request.getServletContext();

        // 向应用域中存储数据
        application.setAttribute("applicationScope", "我是应用域当中的一条数据");

        return "view";
    }

}

视图页面view:

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

超链接index:

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

测试:

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/533913.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql重启失败

服务器重启了一下&#xff0c;然后启动后发现mysql自动启动没有生效&#xff0c;于是手动通过systemctl启动mysqld&#xff0c;然后就报错:Starting MySQL...........The server quit without updating P[FAILED](/data/mysql/iz2zebvmy1qv3fao9c5riuz.pid). 根据配置my.cnf文…

ccf201509-3模板生成系统(list,map,字符串综合运用)

问题描述 成成最近在搭建一个网站&#xff0c;其中一些页面的部分内容来自数据库中不同的数据记录&#xff0c;但是页面的基本结构是相同的。例如&#xff0c;对于展示用户信息的页面&#xff0c;当用户为 Tom 时&#xff0c;网页的源代码是&#xff1a; 而当用户为 Jerry 时…

R语言ggplot2绘图学习笔记(基础知识大全)

R语言ggplot2绘图入门笔记 今天分享的内容是在R语言中利用ggplot2进行可视化的入门笔记&#xff0c;适用于初学者了解ggplot2绘图系统。干货满满&#xff0c;建议收藏&#xff01; 首先安装以下R包&#xff1a; install.packages(c("tidyverse", "colorspace&qu…

为什么学生很难真正学好嵌入式?

10几年前&#xff0c;我是读电气工程专业&#xff0c;学了很多东西&#xff0c;结构&#xff0c;电机、绘图&#xff0c;plc等等.. 其实&#xff0c;都没什么鸟用&#xff0c;出来还是像个废物。 后面我自学转了单片机开发&#xff0c;说句难听点&#xff0c;自己买个开发板都比…

数据科学家常用的24个Python库,2024年最新美团架构师深入讲解Python开发

Scikit-learn是构建模型的Python库。事实上&#xff0c;scikit-learn建立在NumPy&#xff0c;SciPy和matplotlib之上。 TensorFlow TensorFlow由Google开发&#xff0c;是一个流行的深度学习库&#xff0c;可帮助您构建和训练不同的模型。 PyTorch PyTorch是一个基于Python…

强化学习MPC——(一)

目录 1.什么是强化学习2.强化学习的发展历史2.1最优控制2.2试错学习2.3时间差分&#xff08;TD&#xff09;学习 3强化学习的分类4强化学习基本概念 1.什么是强化学习 强化学习是机器学习的一种&#xff0c;是一种介于监督学习和非监督学习的机器学习方法。 学习二字就很形象…

在线预约小程序怎么做

在快节奏的现代生活中&#xff0c;无论是预约理发、还是预定餐厅&#xff0c;亦或是挂号就医&#xff0c;我们都希望有一个更加便捷、高效的方式来完成这些任务。而今&#xff0c;随着科技的发展&#xff0c;一款全新的在线预约小程序应运而生&#xff0c;为我们的生活带来了前…

全局锁和表锁 :给表加个字段怎么有这么多阻碍?

全局锁和表锁 &#xff1a;给表加个字段怎么有这么多阻碍&#xff1f; 今天我要跟你聊聊 MySQL 的锁。数据库锁设计的初衷是处理并发问题。作为多用户共享的资源&#xff0c;当出现并发访问的时候&#xff0c;数据库需要合理地控制资源的访问规则。而锁就是用来实现这些访问规则…

微信小程序页面交互综合练习 (重点:解决“setData of undefined”报错问题)

一、写一个注册表单&#xff0c;点击“注册”按钮将用户输入的数据带到服务器&#xff0c;并且能在控制台显示参数。 &#xff08;1&#xff09;首先&#xff0c;我需要在vscode里面创建一个简易的node.js服务器 //第一步:引入http模块 var http require(http); //第二步:创建…

“上帝粒子”之父、诺贝尔奖得主彼得·希格斯逝世

4月10日&#xff0c;提出希格斯玻色子理论的英国物理学家彼得希格斯&#xff08;Peter Higgs&#xff09;逝世&#xff0c;享年94岁。 这位揭示粒子如何构成宇宙基础的研究先锋、诺贝尔奖得主在爱丁堡的家中去世。 希格斯玻色子&#xff0c;又叫作“上帝粒子”。 最初上帝粒子一…

全光谱台灯哪个牌子好,2024全光谱护眼台灯推荐

近年来&#xff0c;全光谱台灯悄然跻身于家庭必备品之列&#xff0c;赢得了众多消费者的好评。它们以减轻眼睛疲劳的功效而受到推崇&#xff0c;尽管也有声音质疑其实际效用&#xff0c;认为所谓的益处不过是一种心理安慰。面对这些相互矛盾的观点&#xff0c;许多消费者感到困…

前端学习<四>JavaScript基础——16-内置对象:Number和Math

内置对象 Number 的常见方法 Number.isInteger() 判断是否为整数 语法&#xff1a; 布尔值 Number.isInteger(数字); toFixed() 小数点后面保留多少位 语法&#xff1a; 字符串 myNum.toFixed(num); 解释&#xff1a;将数字 myNum 的小数点后面保留 num 位小数&#xff…

解决Django中的UnicodeDecodeError问题

在使用Django进行Web开发时&#xff0c;有时会遇到一些由于编码不一致引起的问题&#xff0c;特别是在处理文件读写操作时。一个常见的错误是UnicodeDecodeError&#xff0c;其表现为gbk codec cant decode byte 0xa6 in position 9737: illegal multibyte sequence。这个问题通…

2024最新最简单的安卓底部菜单栏教程

2024最新最简单的安卓底部菜单栏教程 大界面跳转 public class MainActivity extends AppCompatActivity {Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);BottomNavigationView b…

【吊打面试官系列】Java高并发篇 - 什么是Java Executors 框架?

大家好&#xff0c;我是锋哥。今天分享关于 【什么是Java Executors 框架&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 什么是Java Executors 框架&#xff1f; Executor 框架是一个根据一组执行策略调用&#xff0c;调度&#xff0c;执行和控制的异步任务的…

DVWA -File Upload-通关教程-完结

DVWA -File Upload-通关教程-完结 文章目录 DVWA -File Upload-通关教程-完结页面功能LowMediumHighImpossible 页面功能 此页面的功能为选择某个图片文件点击Upload按钮上传&#xff0c;上传成功后得知文件上传路径为DVWA\hackable\uploads。 Low 源码审计 这段 PHP 代码…

web自动化测试系列-selenium xpath定位方法详解(六)

1.xpath介绍 XPath 是一门在 XML 文档中查找信息的语言。XPath 用于在 XML 文档中通过元素和属性进行导航。而html中也应用了这种语言 &#xff0c;所以 &#xff0c;我们定位html页面元素时也会用到xpath这种方法 。 2.xpath定位方式 xpath主要通过以下四种方法定位 &#…

Redis第12讲——缓存的三种设计模式

缓存的使用在项目中是极其常见的&#xff0c;如果使用得当&#xff0c;缓存可谓时提升系统性能的最简单方法之一&#xff0c;反之则会出现一些莫名其妙的问题&#xff0c;在不同场景下&#xff0c;所使用的缓存策略也是有所变化的&#xff0c;下面我们就介绍一下三种常见的缓存…

appium driver install uiautomator2 安装失败

报错 Installing ‘uiautomator2’ using NPM install spec ‘appium-uiautomator2-driver’ Error: Encountered an error when installing package: npm command ‘install --save-dev --no-progress --no-audit --omitpeer --save-exact --global-style --no-package-lock…

为什么每个人都需要了解这些数据加密技术?

在数字时代&#xff0c;数据加密技术不仅对保护企业的商业秘密至关重要&#xff0c;也是个人隐私安全的重要屏障。随着技术的进步和网络犯罪的增加&#xff0c;数据加密已经成为了信息安全领域的一个热点议题。以下是探讨为什么每个人都需要了解这些数据加密技术的几个主要原因…