SpringMVC--获取请求参数 / 域对象共享数据

news2024/11/15 18:46:29

目录

1. SpringMVC 获取请求参数

1.1. 通过ServletAPI获取

1.2. 控制器方法形参获取

1.3. @RequestParam

1.4. @RequestHeader

1.5. @CookieValue

1.6. 通过POJO获取请求参数

1.7. 解决获取请求参数的乱码问题

2. 域对象共享数据

2.1. 三大域对象

2.2. 准备工作

2.3. ServletAPI向request域对象共享数据

2.3.1. 代码示例

2.3.2. 小总结

2.4. ModelAndView向request域对象共享数据

2.4.1. 代码示例

2.4.2. 小总结

2.5. Model向request域对象共享数据

2.5.1. 代码示例

2.5.2. 小总结

2.6. Map向request域对象共享数据

2.6.1. 代码示例

2.6.2. 小总结

2.7. ModelMap向request域对象共享数据

2.7.1. 代码示例

2.7.2. 小总结

2.8. Model/ModelMap/Map的关系

2.9. 向session域共享数据

2.9.1. 代码示例

2.9.2. 小总结

2.10. 向application域共享数据

2.10.1. 代码示例

2.10.2. 小总结


1. SpringMVC 获取请求参数

在SpringMVC中,获取请求参数是指从客户端(如浏览器)发送的HTTP请求中提取信息的过程。这些信息可以是用户在浏览器地址栏输入的查询字符串中的键值对,也可以是通过表单提交的数据。

当用户访问一个URL时,URL后面经常跟着一些由问号(?)开始,由一系列键值对(param1=value1&param2=value2)组成的查询字符串。在SpringMVC中,你可以通过特定的注解或者方法来获取这些参数的值。

例如,如果你有一个查询字符串example.com?name=Kimi&age=5,你想要获取name的值,你可以在你的控制器方法中使用@RequestParam注解,如下所示:

public String getUserInfo(@RequestParam("name") String name) {
    // 在这里,name变量将会包含"Kimi"
    // ...
}

如果参数是嵌入在URL路径中的,比如example.com/user/1,你可以使用@PathVariable注解来获取路径中的参数值:

public String getUserById(@PathVariable("userId") String userId) {
    // 在这里,userId变量将会包含"1"
    // ...
}

SpringMVC会自动将请求中相应的参数值映射到你的控制器方法的参数上。如果请求中没有相应的参数,而你又没有提供默认值,那么SpringMVC会抛出一个异常。


1.1. 通过ServletAPI获取

在SpringMVC框架中,获取客户端发送的请求参数是一项基本而重要的操作。其中一种方式是利用HttpServletRequest对象,该对象是Servlet API的一部分,提供了对当前HTTP请求的封装和访问。


当你在控制器方法中添加HttpServletRequest作为参数时,你可以直接调用该对象的方法来获取请求中的数据。以下是一个简化的示例,用以解释如何操作:

<a th:ref="@{/testParam}(username='admin', password='123456')">
    测试ServletAPI获取请求参数 </a>
@RequestMapping("/testParam")
public String testParam(HttpServletRequest request){
    // 从请求中获取名为"username"的参数值,并将其存储在局部变量username中
    String username = request.getParameter("username");
    // 从请求中获取名为"password"的参数值,并将其存储在局部变量password中
    String password = request.getParameter("password");
    // 打印获取到的用户名和密码
    System.out.println("username:" + username + ", password:" + password);
    // 返回视图名称,这里为"success"
    return "success";
}

在这个例子中,我们使用了@RequestMapping注解来映射一个特定的URL路径("/testParam")到控制器方法testParam。当有请求发送到这个路径时,SpringMVC会调用这个方法。
在方法内部,我们通过调用HttpServletRequest对象的getParameter方法来获取请求参数。getParameter方法接受一个参数名称作为输入,并返回与该名称对应的请求参数的值。
例如,如果我们的请求URL是http://example.com/testParam?username=admin&password=123456,那么request.getParameter("username")将返回字符串"admin",request.getParameter("password")将返回字符串"123456"。
最后,方法返回一个字符串"success",这通常对应于一个视图名称,SpringMVC的视图解析器会根据这个名称来渲染相应的页面。


1.2. 控制器方法形参获取

在SpringMVC中,除了通过HttpServletRequest对象获取请求参数外,还可以直接通过控制器方法的参数来获取。这种方式更为直观和便捷。

首先,假设你有一个HTML页面,其中包含一个链接,如下所示:

<a th:href="@{/testParam(username='admin',password=123456)}">
  测试获取请求参数-->/testParam </a>

这里使用了Thymeleaf模板引擎(由th:前缀标识)来构建一个指向/testParam路径的链接,并且预先设置了usernamepassword两个请求参数的值。当用户点击这个链接时,浏览器会向服务器发送一个包含这两个参数的GET请求。

接下来,在SpringMVC的控制器中,你可以定义一个方法来处理这个请求,如下所示:

@RequestMapping("/testParam")
public String testParam(String username, String password){
    System.out.println("username:" + username + ", password: " + password);
    return "success";
}

在这个例子中,@RequestMapping注解将/testParam路径的请求映射到了testParam方法。方法中的两个参数usernamepassword与请求中的参数同名。当请求到达时,SpringMVC会自动将请求参数的值赋给控制器方法的对应参数。

现在,如果你的请求中有多个同名参数,例如:

http://example.com/testParam?username=Kimi&username=Admin

在这种情况下,如果你想接收所有的username参数,你可以在控制器方法中使用字符串数组来接收:

@RequestMapping("/testParam")
public String testParam(String[] usernames, String password){
    System.out.println("usernames: " + Arrays.toString(usernames) + ", password: " + password);
    return "success";
}

这里,usernames是一个字符串数组,它将包含所有名为username的请求参数的值。Arrays.toString方法用于将数组转换为字符串,以便于打印输出。

如果你仍然只想要一个单一的字符串参数,即使有多个同名参数,你可以保持使用单个字符串类型的参数。在这种情况下,SpringMVC会取最后一个同名参数的值作为该参数的值。在上面的例子中,username参数的值将会是"Admin",因为这是请求中username参数的最后一个值。


1.3. @RequestParam

@RequestParam 是在Spring框架中使用的注解,它允许你将HTTP请求的参数映射到你的控制器方法的参数上。这个注解主要用于处理请求参数,提供了一种灵活的方式来获取和验证这些参数。

这个注解的三个主要属性是

  1. value:这个属性用于指定HTTP请求参数的名称。当你在方法的参数前使用@RequestParam注解时,可以通过value属性来明确指定你想要从请求中获取哪个参数。例如,如果你有一个名为page的请求参数,你可以这样使用@RequestParam
@GetMapping("/users")
public String getUsers(@RequestParam(value = "page") int pageNumber) {
    // ...
}

在这个例子中,value="page"告诉Spring框架,你想要将请求中的page参数映射到pageNumber变量上。

  1. required:这个属性是一个布尔值,用于指示请求中是否必须包含指定的参数。默认情况下,required属性的值是true,这意味着请求必须包含value属性指定的参数。如果请求中没有这个参数,或者参数的值为空,那么就会抛出一个400错误,提示参数缺失。
    如果将required属性设置为false,那么这个参数就不再是必须提供的。在这种情况下,如果请求中没有提供该参数,或者参数值为空,那么方法的参数将会被赋予null值。

  1. defaultValue:这个属性允许你为参数指定一个默认值。无论required属性是true还是false,如果请求中没有提供value指定的参数,或者参数值为空,那么方法的参数将会被赋予defaultValue属性指定的值。
    例如:
@GetMapping("/users")
public String getUsers(@RequestParam(value = "page", required = false, 
        defaultValue = "1") int pageNumber) {
    // ...
}

在这个例子中,如果请求中没有page参数,或者page参数的值为空,那么pageNumber将会被赋予默认值1

当然可以。以下是一个使用@RequestParam注解的简单Spring MVC控制器方法的例子。这个例子中,我们将创建一个处理HTTP GET请求的方法,该方法接受一个可选的查询参数sort,用于指定返回用户列表的排序方式。

举个栗子

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    // 定义一个处理"/users"路径GET请求的方法
    @GetMapping("/users")
    public String getUsers(
            // 使用@RequestParam注解来绑定请求参数到方法的参数
            @RequestParam(value = "sort", required = false, 
                defaultValue = "name") String sort) {
        
        // 这个方法将会根据sort参数的值返回不同的字符串
        if ("name".equals(sort)) {
            return "Users are sorted by name.";
        } else if ("age".equals(sort)) {
            return "Users are sorted by age.";
        } else {
            return "Invalid sorting parameter.";
        }
    }
}

在这个例子中,我们定义了一个名为getUsers的方法,它映射到HTTP GET请求的/users路径。这个方法有一个参数sort,我们使用@RequestParam注解来绑定请求中的sort查询参数到这个方法的参数上。

  • value = "sort":这指定了请求参数的名称,即我们在URL中使用的名称。例如,在浏览器中访问http://localhost:8080/users?sort=name时,sort就是请求参数的名称。
  • required = false:这表明sort参数是可选的。如果请求中没有提供这个参数,那么方法的sort参数将会是null
  • defaultValue = "name":这为sort参数提供了一个默认值。如果请求中没有sort参数,或者参数值为空字符串,那么sort参数将会被赋予默认值"name"

所以,如果你访问http://localhost:8080/users,没有提供sort参数,那么getUsers方法将会返回"Users are sorted by name.",因为sort参数的默认值是"name"。如果你提供了sort参数,比如访问http://localhost:8080/users?sort=age,那么它将会返回"Users are sorted by age."。如果你提供了一个无效的参数,比如http://localhost:8080/users?sort=height,那么它将会返回"Invalid sorting parameter."


1.4. @RequestHeader

@RequestHeader注解在Spring框架中用于将HTTP请求头信息映射到控制器方法的参数上。这个注解允许你访问和处理请求头中的信息,例如认证令牌、客户端信息等。用法同@RequestParam。

@RequestHeader注解三个属性的简单解释

  1. value:这个属性用于指定HTTP请求头的名称。当你在方法的参数前使用@RequestHeader注解时,通过value属性来明确指出你想要获取哪个请求头的值。例如,如果你想获取名为Authorization的请求头,你可以这样使用@RequestHeader
@GetMapping("/resource")
public String getResource(
    @RequestHeader(value = "Authorization") String authHeader) {
    // ...
}

在这个例子中,value="Authorization"告诉Spring框架,你想要将请求中的Authorization请求头的值映射到authHeader变量上。

  1. required:这个属性是一个布尔值,用来指示请求头是否必须存在于请求中。默认情况下,required的值是true,这意味着请求必须包含value属性指定的请求头。如果请求中缺少这个请求头,那么将会抛出一个异常。
    如果将required属性设置为false,那么这个请求头就不是必须提供的。在这种情况下,如果请求中没有提供该请求头,那么方法的参数将会被赋予null值。

  1. defaultValue:这个属性允许你为请求头指定一个默认值。无论required属性是true还是false,如果请求中没有提供value指定的请求头,或者请求头的值为空,那么方法的参数将会被赋予defaultValue属性指定的值。

举个栗子,创建一个处理HTTP GET请求的方法,该方法接受一个名为User-Agent的请求头,这个请求头通常包含了发出请求的客户端(如浏览器)的信息。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ResourceController {

    // 定义一个处理"/resource"路径GET请求的方法
    @GetMapping("/resource")
    public String getResource(@RequestHeader(value = "User-Agent", 
        required = false, defaultValue = "Unknown") String userAgent) {
        
        // 这个方法将会根据User-Agent请求头发送不同的响应
        return "The resource was requested by: " + userAgent;
    }
}

在这个例子中,我们定义了一个名为getResource的方法,它映射到HTTP GET请求的/resource路径。这个方法有一个参数userAgent,我们使用@RequestHeader注解来绑定请求中的User-Agent请求头到这个方法的参数上。

  • value="User-Agent":这指定了请求头的名称,即我们想要获取的请求头的名称。在这个例子中,我们关注的是User-Agent请求头。
  • required = false:这表明User-Agent请求头不是必须提供的。如果请求中没有这个请求头,或者请求头的值为空字符串,那么userAgent参数将会是null
  • defaultValue = "Unknown":这为User-Agent请求头提供了一个默认值。如果请求中没有提供User-Agent请求头,或者请求头的值为空,那么userAgent参数将会被赋予默认值"Unknown"

所以,如果你访问/resource路径,并且你的浏览器提供了User-Agent请求头,那么getResource方法将会返回包含这个请求头信息的字符串。如果你的请求没有包含User-Agent请求头,或者请求头的值为空,那么方法将会返回一个字符串,表明请求是由一个未知的客户端发起的。


1.5. @CookieValue

@CookieValue注解在Spring框架中用于将HTTP请求中的cookie值映射到控制器方法的参数上。这个注解允许你轻松地读取和处理客户端发送的cookie数据。

@CookieValue注解三个属性:

  1. value:这个属性用来指定cookie的名称。当你使用@CookieValue注解时,通过value属性来明确你想要从请求的cookie中获取哪个cookie的值。例如,如果你的请求中有一个名为sessionToken的cookie,你可以这样使用@CookieValue
@GetMapping("/dashboard")
public String getDashboard(
    @CookieValue(value = "sessionToken") String sessionToken) {
    // ...
}

在这个例子中,value="sessionToken"告诉Spring框架,你想要将名为sessionToken的cookie的值映射到sessionToken变量上。

  1. required:这个属性是一个布尔值,用来指示请求中是否必须包含指定的cookie。默认情况下,required的值是true,这意味着请求必须包含value属性指定的cookie。如果请求中缺少这个cookie,那么将会抛出一个异常。
    如果将required属性设置为false,那么这个cookie就不是必须提供的。在这种情况下,如果请求中没有提供该cookie,那么方法的参数将会被赋予null值。

  1. defaultValue:这个属性允许你为cookie指定一个默认值。无论required属性是true还是false,如果请求中没有提供value指定的cookie,或者cookie的值为空,那么方法的参数将会被赋予defaultValue属性指定的值。

举个栗子

import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CookieController {

    // 定义一个处理"/dashboard"路径GET请求的方法
    @GetMapping("/dashboard")
    public String showDashboard(
        @CookieValue(value = "sessionToken", required = false,
        defaultValue = "no_session") String sessionToken) {
        
        // 这个方法将会根据sessionToken的值来显示不同的信息
        if ("admin".equals(sessionToken)) {
            return "Welcome back, Admin!";
        } else if ("user".equals(sessionToken)) {
            return "Hello, User!";
        } else {
            return "You are not logged in.";
        }
    }
}

定义了一个名为showDashboard的方法,它映射到HTTP GET请求的/dashboard路径。这个方法有一个参数sessionToken,我们使用@CookieValue注解来绑定请求中的名为sessionToken的cookie的值到这个方法的参数上。

  • value="sessionToken":这指定了cookie的名称,即我们想要获取的cookie的名称。
  • required = false:这表明sessionTokencookie不是必须提供的。如果请求中没有这个cookie,或者cookie的值为空字符串,那么sessionToken参数将会是null
  • defaultValue = "no_session":这为sessionTokencookie提供了一个默认值。如果请求中没有提供sessionTokencookie,或者cookie的值为空,那么sessionToken参数将会被赋予默认值"no_session"

所以,如果你访问/dashboard路径,并且你的请求包含了名为sessionToken的cookie,那么showDashboard方法将会根据cookie的值来返回不同的欢迎信息。如果你的请求没有包含sessionTokencookie,或者cookie的值为空,那么方法将会返回一条信息,表明用户未登录。


1.6. 通过POJO获取请求参数

在Spring框架中,可以通过POJO(Plain Old Java Object,简单的旧Java对象)来获取HTTP请求的参数。这意味着你可以创建一个普通的Java类,其属性与请求参数的名称相匹配,Spring框架会自动将请求参数的值绑定到这个类的实例上。

举个栗子

定义一个简单的Java类User,它将代表我们要从请求中获取的数据:

public class User {
    private String username;
    private String password;
    private String sex;
    private int age;
    private String email;

    // 省略getter和setter方法
}

创建一个Spring控制器,它将处理一个提交到/testpojo路径的POST请求:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class UserController {

    // 处理对/testpojo路径的POST请求
    @RequestMapping(value = "/testpojo", method = RequestMethod.POST)
    public String testPOJO(User user) {
        // 打印User对象的信息
        System.out.println(user);
        // 返回一个字符串表示请求已成功处理
        return "success";
    }
}

在这个控制器中,我们定义了一个方法testPOJO,它接受一个User类型的参数。当一个POST请求到达/testpojo路径时,Spring框架会自动将请求中的参数绑定到User对象的属性上,前提是请求参数的名称必须与User类中属性的名称相匹配。

假设用户通过前面提供的HTML表单提交了数据,表单中的字段如下:

<form action="/testpojo" method="post">
    用户名:<input type="text" name="username" value="张三"><br>
    密码:<input type="password" name="password" value="123"><br>
    性别:<input type="radio" name="sex" value="男" checked>男<input type="radio" name="sex" value="女">女<br>
    年龄:<input type="text" name="age" value="23"><br>
    邮箱:<input type="text" name="email" value="123@qq.com"><br>
    <input type="submit" value="提交">
</form>

当用户填写表单并点击提交按钮时,表单数据会被发送到服务器。Spring框架会创建一个User对象,并根据表单中的输入字段自动填充usernamepasswordsexageemail属性。

testPOJO方法中,我们打印出User对象的内容,结果可能如下:

User{username='张三', password='123', sex='男', age=23, email='123@qq.com'}

最后,该方法返回一个字符串"success",表示请求已成功处理。这个例子展示了如何使用POJO来简化请求参数的绑定和处理过程。


1.7. 解决获取请求参数的乱码问题

在Web开发中,乱码问题通常是由于客户端和服务器端在字符编码上不匹配导致的。为了解决这个问题,我们需要确保在数据传输过程中使用统一的字符编码。在Spring MVC中,可以通过配置CharacterEncodingFilter来解决获取请求参数时出现的乱码问题。

CharacterEncodingFilter是Spring提供的一个过滤器,它可以强制请求和响应使用指定的字符编码,通常是UTF-8。这个过滤器需要在web.xml文件中进行注册,以便在请求处理之前对字符编码进行正确的设置。

下面是一个配置CharacterEncodingFilter的例子:

<!-- 配置springMVC的编码过滤器 -->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceResponseEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

在这个配置中,我们定义了一个名为CharacterEncodingFilter的过滤器,并指定了它的类为org.springframework.web.filter.CharacterEncodingFilter。我们设置了两个初始化参数:

  1. encoding:这个参数指定了过滤器使用的字符编码,这里我们设置为UTF-8,这是一种广泛使用的字符编码,可以表示几乎所有语言的字符。
  2. forceResponseEncoding:这个参数设置为true,意味着过滤器会强制响应(即服务器发送给客户端的数据)也使用UTF-8编码。

最后,我们通过<filter-mapping>将过滤器映射到所有的URL路径(/*)。

注:在Spring MVC中,处理编码的CharacterEncodingFilter应该配置在其他过滤器之前,这是因为过滤器是按它们在web.xml中出现的顺序来执行的。如果你有其他过滤器(比如日志记录过滤器、安全过滤器等),你需要确保CharacterEncodingFilter是第一个执行的,以便在其他过滤器处理请求之前就设置好正确的字符编码。这样可以确保整个请求处理过程中字符编码的一致性,避免乱码问题的发生。


2. 域对象共享数据

域对象共享数据是一种在Web应用程序中常见的概念,它涉及到在不同请求之间保持和共享数据的需求。在Web开发中,由于HTTP协议是无状态的,这意味着服务器默认情况下不会记住之前的请求信息。然而,在实际应用中,我们经常需要在多个页面或者多个请求之间共享某些数据,这时候就需要用到域对象。

域对象(Session Object)是一种用于存储用户特定数据的对象,它可以跨越多个页面请求和多个会话。简单来说,就像你在商场购物,你的购物车会随着你在不同商店之间走动而一直跟着你,直到你完成购物。在Web应用程序中,域对象就像这个购物车,它允许服务器跟踪用户的状态和信息,如登录信息、用户偏好设置等。


2.1. 三大域对象

域对象是一种用于存储和传递数据的对象,在不同的范围之间传递数据。不同的域对象代表不同的范围,并且共享数据的范围也不同。

在web项目中,我们通常会使用请求域、会话域应用域这三种域对象。

举个简单的例子就是:

请求域对象是HttpServletRequest:它与单个请求关联,用于在处理一个特定请求的过程中传递数据。这个对象是临时存在的,一旦请求结束就不存在了。就像张三的工位一样,只有他可以使用工位上的东西,一旦他离开工位,其他人就无法使用了。

会话域对象是HttpSession:这个对象与用户会话关联,用于在整个会话期间传递数据,可以跨越多个请求。它与办公室的公共区有些相似,因为办公室内的所有人都可以访问这个区域,就像在同一会话中的所有人都可以访问HttpSession对象一样。

应用域对象是ServletContext:这个对象是整个Web应用程序的上下文,它可以被该应用程序中的所有用户访问。它类似于楼层走廊区,因为该楼层的所有人都可以访问这个区域,就像使用该应用程序的所有用户都可以访问ServletContext对象一样。


  • 请求域

  • 会话域

  • 应用域


2.2. 准备工作

创建子模块SpringMVC-demo03

添加依赖

<dependencies>
    <!-- SpringMVC -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.14</version>
    </dependency>
    
    <!-- 日志 -->
    <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-c
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.4.14</version>
        <!--<scope>test</scope>-->
    </dependency>
    
    <!-- ServletAPI -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>
    
    <!--Spring5和Thymeleaf整合包-->
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring5</artifactId>
        <version>3.0.12.RELEASE</version>
    </dependency>
</dependencies>

设置打包方式,添加 webapp,创建 web.xml 文件

设置编码过滤器

<!-- 定义web应用程序的配置 -->
<!-- 配置springMVC的编码过滤器,确保请求和响应的编码为UTF-8 -->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
        <!-- 指定请求和响应的编码格式为UTF-8 -->
    </init-param>
    <init-param>
        <param-name>forceResponseEncoding</param-name>
        <param-value>true</param-value>
        <!-- 强制响应使用指定的编码格式 -->
    </init-param>
</filter>
<!-- 映射编码过滤器到所有请求 -->
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

配置springMvc的前端控制器Dispatcherservlet

<!-- 配置Spring MVC核心控制器(DispatcherServlet) -->
<servlet>
    <servlet-name>springMVC</servlet-name>
    <!-- 指定DispatcherServlet的全限定类名 -->
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <!-- 初始化参数配置 -->
    <init-param>
        <!-- 参数名:指定Spring MVC配置文件的位置 -->
        <param-name>contextConfigLocation</param-name>
        <!-- 参数值:设置Spring MVC配置文件的路径 -->
        <param-value>classpath:SpringMVC-config.xml</param-value>
    </init-param>

    <!-- 设置DispatcherServlet在应用启动时加载的优先级,值越小,优先级越高 -->
    <load-on-startup>1</load-on-startup>
</servlet>

<!-- 配置Spring MVC核心控制器的请求映射规则 -->
<servlet-mapping>
    <!-- 与上述<servlet>标签中定义的<servlet-name>对应 -->
    <servlet-name>springMVC</servlet-name>
    <!-- URL模式:所有以'/'开头的请求都将交由该DispatcherServlet处理 -->
    <url-pattern>/</url-pattern>
</servlet-mapping>

完整 web.xml 配置如下

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!-- 配置springMVC的编码过滤器,确保请求和响应的编码为UTF-8 -->
    <filter>
        <filter-name>EncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
            <!-- 指定请求和响应的编码格式为UTF-8 -->
        </init-param>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
            <!-- 强制响应使用指定的编码格式 -->
        </init-param>
    </filter>
    <!-- 映射编码过滤器到所有请求 -->
    <filter-mapping>
        <filter-name>EncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <!-- 配置Spring MVC核心控制器(DispatcherServlet) -->
    <servlet>
        <servlet-name>springMVC</servlet-name>
        <!-- 指定DispatcherServlet的全限定类名 -->
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        
        <!-- 初始化参数配置 -->
        <init-param>
            <!-- 参数名:指定Spring MVC配置文件的位置 -->
            <param-name>contextConfigLocation</param-name>
            <!-- 参数值:设置Spring MVC配置文件的路径 -->
            <param-value>classpath:SpringMVC-config.xml</param-value>
        </init-param>
        
        <!-- 设置DispatcherServlet在应用启动时加载的优先级,值越小,优先级越高 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <!-- 配置Spring MVC核心控制器的请求映射规则 -->
    <servlet-mapping>
        <!-- 与上述<servlet>标签中定义的<servlet-name>对应 -->
        <servlet-name>springMVC</servlet-name>
        <!-- URL模式:所有以'/'开头的请求都将交由该DispatcherServlet处理 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

创建测试类

package com.sakurapaid.mvc.test;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class TestController {
    @RequestMapping("/")
    public String test()
    {
        return "index";
    }
}

设置 Spring 配置文件--SpringMVC-config.xml

再 resource 文件夹下创建

添加组件扫描

<!-- 开启组件扫描,自动发现并注册Bean到Spring容器中 -->
<context:component-scan base-package="com.sakurapaid.mvc"/>

配置视图解析器

<!-- 配置JSP视图解析器 -->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="order" value="1"/> <!-- 解析器的优先级 -->
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
    <property name="contentType" value="text/html;charset=UTF-8"/>
</bean>

<!-- 可选,配置html视图解析器 -->
<!-- 配置Thymeleaf视图解析器,用于将控制器返回的逻辑视图名解析为实际的HTML页面 -->
    <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
        <property name="order" value="1"/> <!-- 解析器的优先级 -->
        <property name="characterEncoding" value="UTF-8"/> <!-- 解析结果的字符编码 -->
        <property name="templateEngine">
            <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
                <property name="templateResolver">
                    <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
                        
                        <!-- 设置视图的前缀,例如:如果逻辑视图名为home,则实际查找的路径为/WEB-INF/templates/home.html -->
                        <property name="prefix" value="/WEB-INF/templates/"/>
                        
                        <!-- 设置视图的后缀,即视图文件的扩展名 -->
                        <property name="suffix" value=".html"/>
                        <property name="templateMode" value="HTML5"/> <!-- 指定模板解析模式为HTML5 -->
                        <property name="characterEncoding" value="UTF-8"/> <!-- 模板的字符编码 -->
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

完整代码如下

<?xml version="1.0" encoding="UTF-8"?>
<!-- Spring核心 beans 命名空间 -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd 
           http://www.springframework.org/schema/context 
           https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启组件扫描,自动发现并注册Bean到Spring容器中 -->
    <context:component-scan base-package="com.sakurapaid.mvc"/>
    
    <!-- 配置JSP视图解析器 -->
    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="order" value="1"/> <!-- 解析器的优先级 -->
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
        <property name="contentType" value="text/html;charset=UTF-8"/>
    </bean>
    
</beans>

创建前端 jsp 页面代码

根据视图解析器规则,jsp 文件存放位置应该是 WEB-INF 下的 jsp 文件夹下

test.jsp 文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>我是测试文件</h1>
</body>
</html>

配置本地服务器

注意是对应的工件部署

测试成功


2.3. ServletAPI向request域对象共享数据

2.3.1. 代码示例

index.jsp 界面代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>首页</h1>
    <%--使用ServletAPI向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/RequestByServletAPI">ServletAPI</a>
</body>
</html>

Controller 控制器

package com.sakurapaid.mvc.test;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

/**
 * TestController类用于处理请求。
 */
@Controller
public class TestController {

    /**
     * 处理"/RequestByServletAPI"请求的方法。
     *
     * @param request HttpServletRequest对象,用于获取请求信息和设置响应信息。
     * @return 返回一个字符串"success",指示视图解析器解析成功。
     */
    @RequestMapping("/RequestByServletAPI")
    public String test(HttpServletRequest request)
    {
        // 设置请求属性"testScope"的值为"hello,servletAPI"
        request.setAttribute("testScope", "hello,servletAPI");
        return "success";
    }
}

成功跳转界面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- 页面定义部分,指定页面的输出内容类型和使用的语言 -->
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>Success</h1>
    <!-- 显示操作成功的标题 -->
    <p>从请求作用域获取的值: ${testScope}</p>
    <!-- 通过表达式从请求作用域中获取名为"testScope"的属性值,并显示在页面上 -->
</body>

</html>

测试输出


2.3.2. 小总结

代码过程

  1. index.jsp 是一个网页文件,用户可以在浏览器中看到和与之交互。在这个页面上,有一个链接,当用户点击这个链接时,浏览器会向服务器发送一个请求。
  2. Controller 控制器 (TestController) 是服务器端的一个组件,它的任务是处理来自index.jsp页面的链接点击请求。当请求到来时,它会执行 test 方法。
  3. test 方法中,使用 request.setAttribute("testScope", "hello,servletAPI") 这行代码,我们实际上是在请求对象上加了一个标签(称为“属性”),这个标签的名字是 "testScope",值是 "hello,servletAPI"。你可以把这个过程想象成在信封上贴了一个标签,这样邮递员(这里的邮递员就是浏览器)就知道要把信封(请求)送到哪里,并且知道里面装的是什么。
  4. 然后,test 方法返回一个字符串 "success",这个字符串告诉Spring框架,处理请求成功后,应该显示名为 "success" 的视图(在这个例子中,就是一个JSP页面)。
  5. 成功跳转界面 是用户在浏览器中看到的另一个网页,当请求成功处理后,浏览器会显示这个页面。在这个页面的代码中,有一段 <p> 标签,它包含了一个表达式 ${testScope}。这个表达式的作用是从之前我们在请求对象上贴上的标签(属性)中取出值,并显示在这个段落中。所以,用户会在这个页面上看到 "hello,servletAPI" 这段文字。

总结来说,"使用ServletAPI向request域对象共享数据" 就是指我们使用服务器端的代码(Servlet API)来存储和传递信息(在这个例子中是 "hello,servletAPI"),然后在用户的浏览器中显示这些信息。这个过程让我们能够创建动态的、能够响应用户操作的网页。


或者举个例子

想象一下,你在玩一个接力赛跑游戏。在这个游戏中,Servlet API就像是一个接力棒,而request域对象就像是一个可以传递接力棒的盒子。当你跑到终点时,你需要把接力棒放到这个盒子里,这样下一个跑者就可以从盒子中取出接力棒,继续比赛。

在Web开发中,我们也经常需要在不同的部分(比如不同的页面或者不同的请求处理方法)之间传递信息。这就是Servlet API和request域对象发挥作用的地方。

  • Servlet API:它是一组工具,可以帮助我们处理来自用户的请求,并向用户发送响应。就像接力棒一样,它是用来传递信息的媒介。
  • request域对象:这是一个特殊的存储空间,它属于当前用户的请求。你可以把它想象成一个盒子,你可以在这个盒子里放入信息(比如比分、状态等),然后在需要的时候取出来。这个盒子是临时的,只在当前请求过程中有效。

现在,让我们看看这个过程是如何在代码中实现的:

  1. 用户在浏览器中点击一个链接,这个链接会触发服务器上的一个方法(比如 test 方法)。
  2. test 方法中,我们使用 request.setAttribute("testScope", "hello,servletAPI") 这行代码,就像是把一条信息("hello,servletAPI")放入了接力棒(request域对象)中。
  3. 当方法执行完毕,我们返回一个字符串 "success",这告诉系统我们已经处理完请求,并且一切顺利。
  4. 系统随后会加载一个新的页面(成功跳转界面),在这个页面中,我们用 ${testScope} 这个表达式来取出之前放入接力棒(request域对象)中的信息,并显示在页面上。

所以,"使用ServletAPI向request域对象共享数据" 就像是在游戏中传递接力棒,我们把需要的信息放入一个临时的存储空间(request域对象),然后在适当的时候取出来,以供下一步使用。这样,不同的部分就可以共享和使用同一条信息了。


2.4. ModelAndView向request域对象共享数据

2.4.1. 代码示例

修改 index.jsp 代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>首页</h1>
    <%--使用ServletAPI向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/RequestByServletAPI">ServletAPI</a> <br>
    <%--使用ModelAndView向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testModelAndView">ModelAndView</a>
</body>
</html>

控制器类添加新方法

package com.sakurapaid.mvc.test;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

/**
 * TestController类用于处理请求。
 */
@Controller
public class TestController {

    /**
     * 处理"/RequestByServletAPI"请求的方法。
     *
     * @param request HttpServletRequest对象,用于获取请求信息和设置响应信息。
     * @return 返回一个字符串"success",指示视图解析器解析成功。
     */
    @RequestMapping("/RequestByServletAPI")
    public String test(HttpServletRequest request)
    {
        // 设置请求属性"testScope"的值为"hello,servletAPI"
        request.setAttribute("testScope", "hello,servletAPI");
        return "success";
    }

    /**
     * 测试ModelAndView功能的方法。
     * 该方法不接受任何参数,返回一个ModelAndView实例。
     * Model主要用于向请求域共享数据,View主要用于设置视图,实现页面跳转。
     *
     * @return ModelAndView 包含了模型数据和视图名称的对象。
     */
    @RequestMapping("/testModelAndView")
    public ModelAndView testModelAndView(){
        ModelAndView mav = new ModelAndView();

        // 向请求域中添加一个名为"testScope"的对象,其值为"hello,ModelAndView"。
        mav.addObject("testScope", "hello,ModelAndView");

        // 设置视图名称为"success",即将跳转到的页面。
        mav.setViewName("success");

        return mav;
    }

}

success.jsp 目标页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- 页面定义部分,指定页面的输出内容类型和使用的语言 -->
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>Success</h1>
    <!-- 显示操作成功的标题 -->
    <p>从请求作用域获取的值: ${testScope}</p>
    <!-- 通过表达式从请求作用域中获取名为"testScope"的属性值,并显示在页面上 -->
</body>

</html>

测试输出


2.4.2. 小总结

在Web开发中,我们经常需要在服务器端和客户端之间传递信息。为了实现这个目的,我们可以使用不同的技术。在Spring框架中,ModelAndView是一个非常重要的工具,它可以帮助我们将数据从服务器端传递到客户端,并且实现页面的跳转。

  1. 理解ModelAndView: ModelAndView是Spring框架中的一个对象,它包含了两部分信息:模型数据(Model)和视图名称(View)。模型数据是我们要传递给客户端的数据,而视图名称则告诉系统我们要跳转到哪个页面。
  2. 添加数据到模型: 通过调用ModelAndView对象的addObject方法,我们可以将数据添加到模型中。这些数据会被存储在请求域(request scope)中,这意味着数据只会在当前的HTTP请求中有效。
  3. 设置视图名称: 通过调用ModelAndView对象的setViewName方法,我们可以指定一个视图名称。这个名称会被视图解析器用来找到并渲染相应的页面。
  4. 返回ModelAndView对象: 在控制器方法中,我们将填充好的ModelAndView对象返回给Spring框架。框架会根据视图名称找到对应的页面,并把模型数据传递给这个页面。

testModelAndView方法的实现过程:

1. 创建ModelAndView对象

testModelAndView方法中,我们首先创建了一个ModelAndView对象。这个对象将用于存储我们将要传递给视图的数据(模型数据)以及指定要使用的视图(视图名称)。

ModelAndView mav = new ModelAndView();

2. 向模型中添加数据

接下来,我们使用addObject方法将一个属性添加到ModelAndView对象中。这个属性包括一个名称和一个值。在这个例子中,我们添加了一个名为"testScope"的属性,其值为"hello,ModelAndView"

mav.addObject("testScope", "hello,ModelAndView");

这个属性将被存储在HTTP请求的属性中,可以在视图中被访问和展示。

3. 设置视图名称

然后,我们使用setViewName方法来指定当这个ModelAndView对象被返回时,应该使用的视图名称。在这个例子中,我们指定视图名称为"success"。这意味着Spring框架的视图解析器将会寻找名为success.jsp的页面,并将模型数据传递给这个页面。

mav.setViewName("success");

4. 返回ModelAndView对象

最后,我们将填充好的ModelAndView对象返回给Spring框架。框架将处理这个对象,将模型数据传递给指定的视图,并执行页面跳转。

return mav;

5. 视图展示数据

success.jsp页面中,我们使用EL表达式${testScope}来访问并展示ModelAndView对象中添加的"testScope"属性的值。

<p>从请求作用域获取的值: ${testScope}</p>

当用户访问/testModelAndView路径时,testModelAndView方法会被触发,执行上述过程。最终,用户的浏览器会展示success.jsp页面,并在页面上显示"hello,ModelAndView"这个字符串。


2.5. Model向request域对象共享数据

2.5.1. 代码示例

控制器类添加 tesModel 方法

package com.sakurapaid.mvc.test;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

/**
 * TestController类用于处理请求。
 */
@Controller
public class TestController {

    /**
     * 处理"/RequestByServletAPI"请求的方法。
     *
     * @param request HttpServletRequest对象,用于获取请求信息和设置响应信息。
     * @return 返回一个字符串"success",指示视图解析器解析成功。
     */
    @RequestMapping("/RequestByServletAPI")
    public String test(HttpServletRequest request)
    {
        // 设置请求属性"testScope"的值为"hello,servletAPI"
        request.setAttribute("testScope", "hello,servletAPI");
        return "success";
    }

    /**
     * 测试ModelAndView功能的方法。
     * 该方法不接受任何参数,返回一个ModelAndView实例。
     * Model主要用于向请求域共享数据,View主要用于设置视图,实现页面跳转。
     *
     * @return ModelAndView 包含了模型数据和视图名称的对象。
     */
    @RequestMapping("/testModelAndView")
    public ModelAndView testModelAndView(){
        ModelAndView mav = new ModelAndView();

        // 向请求域中添加一个名为"testScope"的对象,其值为"hello,ModelAndView"。
        mav.addObject("testScope", "hello,ModelAndView");

        // 设置视图名称为"success",即将跳转到的页面。
        mav.setViewName("success");

        return mav;
    }
    
    @RequestMapping("/testModel")
    public String testModel(Model model){
        model.addAttribute("testScope", "hello,Model");
        return "success";
    }

}

修改 index.jsp 文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>首页</h1>
    <%--使用ServletAPI向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/RequestByServletAPI">ServletAPI</a> <br>
    <%--使用ModelAndView向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testModelAndView">ModelAndView</a> <br>
    <%--使用Model向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testModel">Model</a>
</body>
</html>

success.jsp 目标页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- 页面定义部分,指定页面的输出内容类型和使用的语言 -->
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>Success</h1>
    <!-- 显示操作成功的标题 -->
    <p>从请求作用域获取的值: ${testScope}</p>
    <!-- 通过表达式从请求作用域中获取名为"testScope"的属性值,并显示在页面上 -->
</body>

</html>

测试输出


2.5.2. 小总结

使用Model向request域对象共享数据的过程:

  1. 创建TestController类:这是一个Spring MVC控制器(@Controller注解),负责处理特定的HTTP请求。
  2. 定义testModel()方法
    • 使用@RequestMapping("/testModel")注解映射到URL路径/testModel
    • 方法接收一个Model类型的参数。Model是Spring MVC提供的一种接口,用于向视图传递模型数据。
    • 在方法内部,调用model.addAttribute("testScope", "hello,Model"),将键为testScope、值为"hello,Model"的数据添加到Model对象中。这一步实际上就是向请求作用域共享数据,因为Model会在渲染视图时将数据放入请求作用域。
  1. 配置success.jsp:作为目标页面,它负责显示从请求作用域获取的数据。
    • 使用JSP表达式 ${testScope} 来从请求作用域获取名为testScope的属性值。
    • success.jsp被渲染时,${testScope}会被替换为实际从请求作用域中获取的值。
  1. 测试过程
    • 用户访问首页index.jsp,点击链接“Model”,发起对/testModel的HTTP请求。
    • Spring MVC框架根据URL路径找到并调用TestController中的testModel()方法。
    • testModel()方法将数据"hello,Model"添加到Model对象,并返回视图名"success"
    • Spring MVC框架根据返回的视图名找到并渲染success.jsp页面。
    • 在渲染过程中,JSP引擎在success.jsp中遇到${testScope}表达式,从当前请求作用域查找并取出对应的值(即"hello,Model"),将其替换到HTML中。
    • 最终用户看到的success.jsp页面上显示了从请求作用域获取的值:“从请求作用域获取的值: hello,Model”。

综上所述,使用Model向request域对象共享数据的过程如下:

  • 在控制器方法中接收一个Model参数,通过调用addAttribute()方法将数据(键值对)添加到Model中。
  • 控制器方法返回视图名,触发视图渲染。
  • 在目标JSP页面中使用${}表达式从请求作用域获取已共享的数据,并动态插入到页面内容中。

2.6. Map向request域对象共享数据

2.6.1. 代码示例

控制器类添加 testMap 方法

package com.sakurapaid.mvc.test;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * TestController类用于处理请求。
 */
@Controller
public class TestController {

    /**
     * 处理"/RequestByServletAPI"请求的方法。
     * 通过HttpServletRequest来处理请求,设置请求属性,并返回一个字符串指示视图解析器如何处理响应。
     *
     * @param request HttpServletRequest对象,用于获取请求信息和设置响应信息。
     * @return 返回一个字符串"success",指示视图解析器解析成功。
     */
    @RequestMapping("/RequestByServletAPI")
    public String test(HttpServletRequest request)
    {
        // 设置请求属性
        request.setAttribute("testScope", "hello,servletAPI");
        return "success";
    }

    /**
     * 测试ModelAndView功能的方法。
     * 该方法不接受任何参数,返回一个ModelAndView实例,用于演示如何使用ModelAndView来处理请求和响应。
     *
     * @return ModelAndView 包含了模型数据和视图名称的对象。
     */
    @RequestMapping("/testModelAndView")
    public ModelAndView testModelAndView(){
        ModelAndView mav = new ModelAndView();

        // 添加模型数据
        mav.addObject("testScope", "hello,ModelAndView");

        // 设置视图名称
        mav.setViewName("success");

        return mav;
    }

    /**
     * 使用Model来传递数据的方法。
     * 通过Model来向请求域添加数据,然后返回一个视图名称。
     *
     * @param model 用于向请求域添加数据的Model对象。
     * @return 返回一个字符串"success",指示视图解析器解析成功。
     */
    @RequestMapping("/testModel")
    public String testModel(Model model){
        // 向Model中添加数据
        model.addAttribute("testScope", "hello,Model");
        return "success";
    }

    /**
     * 使用Map来传递数据的方法。
     * 通过Map来向请求域添加数据,然后返回一个视图名称。
     *
     * @param map 用于向请求域添加数据的Map对象。
     * @return 返回一个字符串"success",指示视图解析器解析成功。
     */
    @RequestMapping("/testMap")
    public String testMap(Map<String, Object> map){
        // 向Map中添加数据
        map.put("testScope", "hello,Map");
        return "success";
    }

}

修改 inde.jsp 文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>首页</h1>
    <%--使用ServletAPI向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/RequestByServletAPI">ServletAPI</a> <br>
    <%--使用ModelAndView向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testModelAndView">ModelAndView</a> <br>
    <%--使用Model向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testModel">Model</a> <br>
    <%--使用Map向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testMap">Map</a>
</body>
</html>

success.jsp 目标页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- 页面定义部分,指定页面的输出内容类型和使用的语言 -->
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>Success</h1>
    <!-- 显示操作成功的标题 -->
    <p>从请求作用域获取的值: ${testScope}</p>
    <!-- 通过表达式从请求作用域中获取名为"testScope"的属性值,并显示在页面上 -->
</body>

</html>

测试输出


2.6.2. 小总结

使用Map向request域对象共享数据的过程如下:

  1. 创建TestController类:这是一个Spring MVC控制器(@Controller注解),负责处理特定的HTTP请求。
  2. 定义testMap()方法
    • 使用@RequestMapping("/testMap")注解映射到URL路径/testMap
    • 方法接收一个Map<String, Object>类型的参数。Map是一个通用的键值对容器,这里用来临时存储要共享的数据。
    • 在方法内部,调用map.put("testScope", "hello,Map"),将键为testScope、值为"hello,Map"的数据放入Map对象中。Spring MVC框架会自动将此Map对象的内容添加到请求作用域,从而实现数据共享。
  1. 配置success.jsp:作为目标页面,它负责显示从请求作用域获取的数据。
    • 使用JSP表达式 ${testScope} 来从请求作用域获取名为testScope的属性值。
    • success.jsp被渲染时,${testScope}会被替换为实际从请求作用域中获取的值。
  1. 测试过程
    • 用户访问首页index.jsp,点击链接“Map”,发起对/testMap的HTTP请求。
    • Spring MVC框架根据URL路径找到并调用TestController中的testMap()方法。
    • testMap()方法将数据"hello,Map"放入Map对象,并返回视图名"success"
    • Spring MVC框架接收到返回的视图名,开始渲染success.jsp页面。
    • 在渲染过程中,JSP引擎在success.jsp中遇到${testScope}表达式,从当前请求作用域查找并取出对应的值(即"hello,Map"),将其替换到HTML中。
    • 最终用户看到的success.jsp页面上显示了从请求作用域获取的值:“从请求作用域获取的值: hello,Map”。

总结起来,使用Map向request域对象共享数据的过程包括:

  • 在控制器方法中接收一个Map参数,通过调用put()方法将数据(键值对)放入Map中。
  • 控制器方法返回视图名,触发视图渲染。
  • 在目标JSP页面中使用${}表达式从请求作用域获取已共享的数据,并动态插入到页面内容中。

需要注意的是,虽然这里使用了Map来传递数据,但实际上是Spring MVC框架自动将Map中的数据添加到了请求作用域。对于初学者来说,更推荐直接使用Model对象(如testModel()方法所示),因为它与Spring MVC框架结合更紧密,使用更直观,且提供了更多与视图渲染相关的便捷功能。使用Map传递数据的方式在某些特殊场景下可能会出现,但在常规开发中并不常见。


2.7. ModelMap向request域对象共享数据

2.7.1. 代码示例

控制器类添加 testModelMap 方法

package com.sakurapaid.mvc.test;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * TestController类用于处理请求。
 */
@Controller
public class TestController {

    /**
     * 处理"/RequestByServletAPI"请求的方法。
     * 通过HttpServletRequest来处理请求,设置请求属性,并返回一个字符串指示视图解析器如何处理响应。
     *
     * @param request HttpServletRequest对象,用于获取请求信息和设置响应信息。
     * @return 返回一个字符串"success",指示视图解析器解析成功。
     */
    @RequestMapping("/RequestByServletAPI")
    public String test(HttpServletRequest request)
    {
        // 设置请求属性
        request.setAttribute("testScope", "hello,servletAPI");
        return "success";
    }

    /**
     * 测试ModelAndView功能的方法。
     * 该方法不接受任何参数,返回一个ModelAndView实例,用于演示如何使用ModelAndView来处理请求和响应。
     *
     * @return ModelAndView 包含了模型数据和视图名称的对象。
     */
    @RequestMapping("/testModelAndView")
    public ModelAndView testModelAndView(){
        ModelAndView mav = new ModelAndView();

        // 添加模型数据
        mav.addObject("testScope", "hello,ModelAndView");

        // 设置视图名称
        mav.setViewName("success");

        return mav;
    }

    /**
     * 使用Model来传递数据的方法。
     * 通过Model来向请求域添加数据,然后返回一个视图名称。
     *
     * @param model 用于向请求域添加数据的Model对象。
     * @return 返回一个字符串"success",指示视图解析器解析成功。
     */
    @RequestMapping("/testModel")
    public String testModel(Model model){
        // 向Model中添加数据
        model.addAttribute("testScope", "hello,Model");
        return "success";
    }

    /**
     * 使用Map来传递数据的方法。
     * 通过Map来向请求域添加数据,然后返回一个视图名称。
     *
     * @param map 用于向请求域添加数据的Map对象。
     * @return 返回一个字符串"success",指示视图解析器解析成功。
     */
    @RequestMapping("/testMap")
    public String testMap(Map<String, Object> map){
        // 向Map中添加数据
        map.put("testScope", "hello,Map");
        return "success";
    }

    /**
     * 使用ModelMap来传递数据的方法。
     * 通过ModelMap来向请求域添加数据,然后返回一个视图名称。
     *
     * @param modelMap 用于向请求域添加数据的ModelMap对象。
     * @return 返回一个字符串"success",指示视图解析器解析成功。
     */
    @RequestMapping("/testModelMap")
    public String testModelMap(ModelMap modelMap){
        modelMap.addAttribute("testScope", "hello,ModelMap");
        return "success";
    }

}

修改 inde.jsp 文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>首页</h1>
    <%--使用ServletAPI向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/RequestByServletAPI">ServletAPI</a> <br>
    <%--使用ModelAndView向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testModelAndView">ModelAndView</a> <br>
    <%--使用Model向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testModel">Model</a> <br>
    <%--使用Map向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testMap">Map</a> <br>
    <%--使用ModelMap向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testModelMap">ModelMap</a>
</body>
</html>

success.jsp 目标页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- 页面定义部分,指定页面的输出内容类型和使用的语言 -->
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>Success</h1>
    <!-- 显示操作成功的标题 -->
    <p>从请求作用域获取的值: ${testScope}</p>
    <!-- 通过表达式从请求作用域中获取名为"testScope"的属性值,并显示在页面上 -->
</body>

</html>

测试输出


2.7.2. 小总结

使用ModelMap向request域对象共享数据的过程与使用Model非常相似,因为ModelMapModel接口的一个实现类。

  1. 定义testModelMap()方法
    • 使用@RequestMapping("/testModelMap")注解映射到URL路径/testModelMap
    • 方法接收一个ModelMap类型的参数。ModelMap是Spring MVC专门为视图模型设计的类,继承自LinkedHashMap,具有Map接口的所有功能,并额外提供了一些便于操作模型数据的方法。
    • 在方法内部,调用modelMap.addAttribute("testScope", "hello,ModelMap"),将键为testScope、值为"hello,ModelMap"的数据添加到ModelMap对象中。ModelMap对象会自动将其内容添加到请求作用域,实现数据共享。
  1. 配置success.jsp:与之前相同,目标页面success.jsp负责从请求作用域获取并显示名为testScope的属性值。
  2. 测试过程
    • 用户访问首页index.jsp,点击链接“ModelMap”,发起对/testModelMap的HTTP请求。
    • Spring MVC框架根据URL路径找到并调用TestController中的testModelMap()方法。
    • testModelMap()方法将数据"hello,ModelMap"添加到ModelMap对象,并返回视图名"success"
    • Spring MVC框架接收到返回的视图名,开始渲染success.jsp页面。
    • 在渲染过程中,JSP引擎在success.jsp中遇到${testScope}表达式,从当前请求作用域查找并取出对应的值(即"hello,ModelMap"),将其替换到HTML中。
    • 最终用户看到的success.jsp页面上显示了从请求作用域获取的值:“从请求作用域获取的值: hello,ModelMap”。

总结起来,使用ModelMap向request域对象共享数据的过程包括:

  • 在控制器方法中接收一个ModelMap参数,通过调用addAttribute()方法将数据(键值对)添加到ModelMap中。
  • 控制器方法返回视图名,触发视图渲染。
  • 在目标JSP页面中使用${}表达式从请求作用域获取已共享的数据,并动态插入到页面内容中。

尽管ModelMap提供了比Map更多的便利功能,但在实际开发中,通常更推荐直接使用Model接口作为方法参数(如testModel()所示)。这样做可以使代码更通用,因为Spring MVC会自动将传入的Model参数转换为合适的实现类(如ModelMapExtendedModelMap)。这样,即使以后Spring MVC内部实现发生变化,你的代码也不需要调整。因此,使用Model作为参数是一种更好的编程习惯。


2.8. Model/ModelMap/Map的关系

在Spring MVC中,当我们在控制器方法(如@RequestMapping注解的方法)中使用Model、ModelMap或Map类型的参数来向request域对象共享数据时,虽然它们表面上看起来不同,但本质上,这些参数都被Spring MVC框架处理为BindingAwareModelMap类型。


  1. Model
    • 接口定义:Model是一个接口,它定义了一组方法,用于在控制器中向一个数据模型添加属性。这些属性在后续的视图渲染过程中可供访问和展示。
    • 简化控制器逻辑:作为开发者,我们无需直接操作底层数据结构,只需通过Model接口提供的方法添加属性,简化了控制器的编码工作。
    • 基于Map的实现:虽然Model接口本身不直接实现Map接口,但在Spring MVC的实际应用中,传入控制器方法的Model参数通常会被实现为一个Map(如BindingAwareModelMap),因此可以像操作Map一样向其中添加键值对。

  1. ModelMap
    • 具体实现:ModelMap是Model接口的一个具体实现类,它不仅提供了Model接口所定义的方法,还内建了一个Map来实际存储属性数据。
    • 增强功能:相较于直接使用Map,ModelMap提供了额外的便利性和功能,如支持批量添加属性、自动类型转换等,使得数据管理更加高效。
    • 常用选择:由于其便捷性和针对视图渲染的优化,ModelMap在Spring MVC应用中被广泛用作控制器与视图间数据传递的标准工具。

  1. Map
    • 通用数据结构:Map是Java标准库中的一个接口,用于表示键值对(key-value pairs)的集合,是一种通用的数据存储结构。
    • 灵活运用:在Spring MVC中,任何实现了Map接口的对象(如HashMapLinkedHashMap等)都可以用来在控制器和视图之间传递数据。这种方式更为底层和灵活,但需要开发者自行处理一些细节问题,如属性添加、类型转换等。
    • 直接使用场景:尽管ModelMap是首选,但在某些特定场景下,开发者可能选择直接使用Map,如需要特定Map实现的特性,或者希望对数据传递过程有更精细的控制。

总结来说,Model作为接口,定义了在控制器和视图间传递数据的基本操作;ModelMap作为Model接口的实现,提供了一个功能丰富、专为Spring MVC优化的属性容器;而Map作为一种通用数据结构,虽然可以直接用于数据传递,但使用时需自行处理更多细节。在日常开发中,ModelMap因其便捷性和针对性优化,成为在Spring MVC中传递模型数据的主流选择。


2.9. 向session域共享数据

2.9.1. 代码示例

控制器类添加 testSession 方法

package com.sakurapaid.mvc.test;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Map;

@Controller
public class TestController {
    /**
     * 测试会话功能的方法。
     * 
     * @param session  HttpSession对象,用于存储和获取会话属性。
     * @return 返回一个字符串"success",表示会话测试成功。
     */
    @RequestMapping("/testSession")
    public String testSession(HttpSession session){
        // 设置会话属性"testScope",值为"hello,session"
        session.setAttribute("testScope", "hello,session");
        return "success";
    }

    /**
     * 处理"/RequestByServletAPI"请求的方法。
     * 通过HttpServletRequest来处理请求,设置请求属性,并返回一个字符串指示视图解析器如何处理响应。
     *
     * @param request HttpServletRequest对象,用于获取请求信息和设置响应信息。
     * @return 返回一个字符串"success",指示视图解析器解析成功。
     */
    @RequestMapping("/RequestByServletAPI")
    public String test(HttpServletRequest request)
    {
        // 设置请求属性
        request.setAttribute("testScope", "hello,servletAPI");
        return "success";
    }

    /**
     * 测试ModelAndView功能的方法。
     * 该方法不接受任何参数,返回一个ModelAndView实例,用于演示如何使用ModelAndView来处理请求和响应。
     *
     * @return ModelAndView 包含了模型数据和视图名称的对象。
     */
    @RequestMapping("/testModelAndView")
    public ModelAndView testModelAndView(){
        ModelAndView mav = new ModelAndView();

        // 添加模型数据
        mav.addObject("testScope", "hello,ModelAndView");

        // 设置视图名称
        mav.setViewName("success");

        return mav;
    }

    /**
     * 使用Model来传递数据的方法。
     * 通过Model来向请求域添加数据,然后返回一个视图名称。
     *
     * @param model 用于向请求域添加数据的Model对象。
     * @return 返回一个字符串"success",指示视图解析器解析成功。
     */
    @RequestMapping("/testModel")
    public String testModel(Model model){
        // 向Model中添加数据
        model.addAttribute("testScope", "hello,Model");
        return "success";
    }

    /**
     * 使用Map来传递数据的方法。
     * 通过Map来向请求域添加数据,然后返回一个视图名称。
     *
     * @param map 用于向请求域添加数据的Map对象。
     * @return 返回一个字符串"success",指示视图解析器解析成功。
     */
    @RequestMapping("/testMap")
    public String testMap(Map<String, Object> map){
        // 向Map中添加数据
        map.put("testScope", "hello,Map");
        return "success";
    }

    /**
     * 使用ModelMap来传递数据的方法。
     * 通过ModelMap来向请求域添加数据,然后返回一个视图名称。
     *
     * @param modelMap 用于向请求域添加数据的ModelMap对象。
     * @return 返回一个字符串"success",指示视图解析器解析成功。
     */
    @RequestMapping("/testModelMap")
    public String testModelMap(ModelMap modelMap){
        modelMap.addAttribute("testScope", "hello,ModelMap");
        return "success";
    }

}

修改 index.jsp 界面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>首页</h1>
    <%--使用ServletAPI向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/RequestByServletAPI">ServletAPI</a> <br>
    <%--使用ModelAndView向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testModelAndView">ModelAndView</a> <br>
    <%--使用Model向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testModel">Model</a> <br>
    <%--使用Map向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testMap">Map</a> <br>
    <%--使用ModelMap向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testModelMap">ModelMap</a> <br>
    <%--使用session域向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testSession">Session</a>
</body>
</html>

测试输出


2.9.2. 小总结

使用HttpSession向session域对象共享数据的过程如下:

  1. 定义testSession()方法
    • 使用@RequestMapping("/testSession")注解映射到URL路径/testSession
    • 方法接收一个HttpSession类型的参数,该参数代表当前用户的会话对象。
    • 在方法内部,调用httpSession.setAttribute("testScope", "hello,Session"),将键为testScope、值为"hello,Session"的数据添加到HttpSession对象中。HttpSession对象用于存储与用户会话相关的数据,这些数据在整个会话期间保持有效,直至会话过期或被显式清除。
  1. 配置success.jsp
    • 目标页面success.jsp负责从session作用域获取并显示名为testScope的属性值。与之前一样,使用${testScope}表达式来获取并显示session域中的数据。
  1. 测试过程
    • 用户访问首页index.jsp,点击链接“Session”,发起对/testSession的HTTP请求。
    • Spring MVC框架根据URL路径找到并调用TestController中的testSession()方法。
    • testSession()方法将数据"hello,Session"添加到HttpSession对象,并返回视图名"success"
    • Spring MVC框架接收到返回的视图名,开始渲染success.jsp页面。
    • 在渲染过程中,JSP引擎在success.jsp中遇到${testScope}表达式,从当前session作用域查找并取出对应的值(即"hello,Session"),将其替换到HTML中。
    • 最终用户看到的success.jsp页面上显示了从session作用域获取的值:“从session作用域获取的值: hello,Session”。

总结起来,使用HttpSession向session域对象共享数据的过程包括:

  • 在控制器方法中接收一个HttpSession参数,通过调用setAttribute()方法将数据(键值对)添加到HttpSession中。
  • 控制器方法返回视图名,触发视图渲染。
  • 在目标JSP页面中使用${}表达式从session作用域获取已共享的数据,并动态插入到页面内容中。

使用HttpSession可以实现跨请求的数据共享,适用于需要在用户整个会话期间持久化数据的场景,如用户登录状态、购物车信息等。但需要注意的是,过度依赖session可能导致内存消耗增加,应合理控制session中存储的数据量和生命周期。


2.10. 向application域共享数据

2.10.1. 代码示例

控制器类添加 testApplication 方法

/**
 * 测试应用程序的范围属性。
 *
 * @param session  HttpSession对象,用于获取Servlet上下文。
 * @return 返回一个字符串"success",表示操作成功。
 */
@RequestMapping("/testApplication")
public String testApplication(HttpSession session){
    // 获取Servlet上下文
    ServletContext application = session.getServletContext();
    // 向Servlet上下文设置一个属性,名称为"testScope",值为"hello,application"
    application.setAttribute("testScope", "hello,application");
    return "success";
}

修改 index.jsp 界面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>首页</h1>
    <%--使用ServletAPI向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/RequestByServletAPI">ServletAPI</a> <br>
    <%--使用ModelAndView向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testModelAndView">ModelAndView</a> <br>
    <%--使用Model向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testModel">Model</a> <br>
    <%--使用Map向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testMap">Map</a> <br>
    <%--使用ModelMap向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testModelMap">ModelMap</a> <br>
    <%--使用session域向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testSession">Session</a>
    <%--使用application域向request域对象共享数据--%>
    <a href="${pageContext.request.contextPath}/testApplication">Application</a>
</body>
</html>

测试输出


2.10.2. 小总结

使用ServletContext向application域对象共享数据的过程:

  1. 定义testApplication()方法
    • 使用@RequestMapping("/testApplication")注解映射到URL路径/testApplication
    • 方法接收一个HttpSession类型的参数,通过该参数获取ServletContext对象(即应用程序上下文)。
    • 在方法内部,调用session.getServletContext()获取ServletContext对象。
    • 调用application.setAttribute("testScope", "hello,application"),将键为testScope、值为"hello,application"的数据添加到ServletContext对象中。ServletContext对象代表整个Web应用程序的全局共享区域,其存储的数据在整个应用程序范围内可见,直到应用程序被重新部署或服务器关闭。
  1. 配置success.jsp
    • 目标页面success.jsp负责从application作用域获取并显示名为testScope的属性值。与之前一样,使用${testScope}表达式来获取并显示application域中的数据。
  1. 测试过程
    • 用户访问首页index.jsp,点击链接“Application”,发起对/testApplication的HTTP请求。
    • Spring MVC框架根据URL路径找到并调用TestController中的testApplication()方法。
    • testApplication()方法将数据"hello,application"添加到ServletContext对象,并返回视图名"success"
    • Spring MVC框架接收到返回的视图名,开始渲染success.jsp页面。
    • 在渲染过程中,JSP引擎在success.jsp中遇到${testScope}表达式,从当前application作用域查找并取出对应的值(即"hello,application"),将其替换到HTML中。
    • 最终用户看到的success.jsp页面上显示了从application作用域获取的值:“从application作用域获取的值: hello,application”。

总结起来,使用ServletContext向application域对象共享数据的过程包括:

  • 在控制器方法中接收一个HttpSession参数,通过其获取ServletContext对象。
  • 调用setAttribute()方法将数据(键值对)添加到ServletContext
  • 控制器方法返回视图名,触发视图渲染。
  • 在目标JSP页面中使用${}表达式从application作用域获取已共享的数据,并动态插入到页面内容中。

使用ServletContext可以在整个Web应用程序范围内共享数据,适用于需要所有用户或所有请求都能访问的全局配置信息、静态资源映射等场景。由于application作用域的生命周期较长,应谨慎管理存储在其中的数据,避免占用过多内存或导致数据泄漏。


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

海外短剧系统开发:引领全球短剧新潮流,打造跨文化娱乐新体验

随着全球化和互联网的快速发展&#xff0c;跨文化娱乐已经成为人们日常生活中不可或缺的一部分。海外短剧作为一种新颖、便捷的娱乐形式&#xff0c;正逐渐受到越来越多观众的喜爱。为了满足广大用户的需求&#xff0c;我们荣幸地推出全新的海外短剧系统开发方案&#xff0c;旨…

IDEA 找不到或无法加载主类

IDEA 中&#xff0c;有时候会遇到明明存在这个类&#xff0c;import 也没有报错&#xff0c;但编译时会报找不到或无法加载主类。 解决方法&#xff1a; 图像化操作 右侧 Maven > 根项目 > Lifecycle > clean > install 命令操作 mvn clean install

Java单例集合

Collection接口介绍 Collection 表示一组对象&#xff0c;它是集中、收集的意思。Collection接口的两个子接口是List、Set接口。 Collection接口中定义的方法 方法说明boolean add(Object element)增加元素到容器中boolean remove(Object element)从容器中移除元素 boolean c…

Angular 使用DomSanitizer防范跨站脚本攻击

跨站脚本Cross-site scripting 简称XSS&#xff0c;是代码注入的一种&#xff0c;是一种网站应用程序的安全漏洞攻击。它允许恶意用户将代码注入到网页上&#xff0c;其他用户在使用网页时就会收到影响&#xff0c;这类攻击通常包含了HTML和用户端脚本语言&#xff08;JS&…

代码随想录算法训练营三刷day55 | 动态规划之子序列 392.判断子序列 115.不同的子序列

day55 392.判断子序列1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组 115.不同的子序列1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历…

【Linux学习】初识Linux指令(二)

文章标题 1.rm 指令2.man指令3.nano指令4.cp指令5.mv指令6.alias指令7. cat与8.echo指令 ⚶文章简介 ⚶本篇文章继上篇文章Linux指令讲解&#xff0c;本篇文章主要会涉及到的指令会有&#xff1a;rm指令与 *&#xff08;通配符&#xff09;的搭配使用&#xff0c;man指令&…

CRMEB 开源/标准版商城系统客服配置教程

管理后台/设置/系统设置/商城配置/客服端配置 有系统客服/拨打电话/跳转链接可选&#xff0c;系统客服为系统自带的客服系统&#xff0c;拨打电话为用户点击联系客服为拨打客服电话的方式&#xff0c;跳转链接为可以跳转自己开发的客服系统或者第三方的客服系统或者企业微信的…

文献学习-33-一个用于生成手术视频摘要的python库

VideoSum: A Python Library for Surgical Video Summarization Authors: Luis C. Garcia-Peraza-Herrera, Sebastien Ourselin, and Tom Vercauteren Source: https://arxiv.org/pdf/2303.10173.pdf 这篇文章主要关注的是如何通过视频摘要来简化和可视化手术视频&#xff0c…

mediapipe人体姿态检测(全方位探索手部、面部识别、姿势识别与物体检测及自拍分割技术)

引言 本文将聚焦于MediaPipe对人体姿态检测的全面支持&#xff0c;包括手部、面部识别、全身姿势识别、物体检测以及自拍分割五大关键技术。通过深入了解这些功能&#xff0c;读者将能更好地运用MediaPipe在各种应用中实现精准的人体动作捕捉与分析。 一、手部关键点检测 Me…

Web应用程序中的常见安全漏洞

大家好&#xff0c;我是咕噜铁蛋&#xff01;今天&#xff0c;我想和大家聊聊一个在我们日常开发中经常遇到的问题——Web应用程序中的安全漏洞。在这个数字化时代&#xff0c;Web应用几乎无处不在&#xff0c;它们不仅方便了我们的生活&#xff0c;也推动了社会的进步。然而&a…

python实现简单的车道线检测

描述 python实现简单的车道线检测&#xff0c;本文章将介绍两种简单的方法 颜色阈值区域掩模canny边缘检测霍夫变换 这两种方法都能实现简单的车道线检测demo&#xff0c;注意仅仅是demo 下面的图片是用到的测试图片 方法1&#xff1a;颜色阈值&#xff08;Color Selection…

李廉洋:4.15黄金,原油最新资讯,美盘走势分析及策略。

由于欧洲央行很可能先于美联储降息&#xff0c;美元走强。法国兴业银行分析师基特•朱克斯表示&#xff0c;市场“假设我们看到欧洲央行将在6月降息&#xff0c;但美联储不会”&#xff0c;这对美元有利。朱克斯表示&#xff0c;尽管在货币政策决定之前会公布一些相关数据&…

JMeter多个线程组的使用说明!

当JMeter测试计划中存在多个线程组&#xff0c;您需要了解如何结合JMeter和PTS配置参数&#xff0c;使多个线程组并行或串行压测。 前提条件 创建JMeter压测场景。具体操作&#xff0c;请参见创建JMeter场景。 背景信息 JMeter线程组包括setUp线程组、tearDown线程组和主线…

升级win11后无线鼠标失灵,win11鼠标用不了

鼠标失灵是常见的设备故障问题,今天带来相关的解决方法,本文主要是针对升级win11后无线鼠标失灵的处理方法。不少小伙伴在使用电脑的过程中,都遇到过鼠标移动缓慢或者动不了的情况,升级到win11系统的小伙伴也不例外。一般刚升级新系统后,才出现的鼠标失灵问题,那么可能会…

硬件资产管理系统你了解吗

企业规模的扩大和信息化程度的提升使得硬件资产管理变得愈发重要。 一个高效、可靠的硬件资产管理系统不仅能够确保企业资产的安全和完整&#xff0c;还能提高资产使用效率&#xff0c;降低管理成本。 一、什么是电脑硬件资产 电脑硬件资产是指构成电脑的物理设备&#xff0c…

JavaScript流文件下载实现详解

文章的更新路线&#xff1a;JavaScript基础知识-Vue2基础知识-Vue3基础知识-TypeScript基础知识-网络基础知识-浏览器基础知识-项目优化知识-项目实战经验-前端温习题&#xff08;HTML基础知识和CSS基础知识已经更新完毕&#xff09; 正文 前端web、h5实现方式 if (!res) retur…

【LeetCode热题100】【回溯】单词搜索

题目链接&#xff1a;79. 单词搜索 - 力扣&#xff08;LeetCode&#xff09; 要在一个二维数组里面找到一条单词路径&#xff0c;可以先遍历二维数组找到单词入口&#xff0c;然后往上下左右深度遍历&#xff0c;访问过的元素直接修改成字符串结束符&#xff0c;访问完改回去 …

报表资产管理

经过日积月累的开发&#xff0c;逐步发现很多报表是没有价值&#xff0c;使用频率低。或者存在报表归属争议问题。报表需求有规划的管理&#xff0c;称之为报表资产管理。下面基于帆软报表体系梳理一下报表资产管理内容。 报表资产管理分为四块内容&#xff1a;基础属性、业务属…

LeetCode-热题100:104. 二叉树的最大深度

题目描述 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a; root [3,9,20,null,null,15,7] 输出&#xff1a; 3 示例 2&#xff1a; 输入&#xff1a; root …

Unity URP PBR_Cook-Torrance模型

Cook-Torrance模型是一个微表面光照模型&#xff0c;认为物体的表面可以看作是由许多个理想的镜面反射体微小平面组成的。 单点反射镜面反射漫反射占比*漫反射 漫反射 基础色/Π 镜面反射DFG/4(NV)(NL) D代表微平面分布函数&#xff0c;描述的是法线与半角向量normalize(L…