1. Spring MVC 獲取三個域(request請求域,session 會話域,application 應用域)物件的方式
@
- 1. Spring MVC 獲取三個域(request請求域,session 會話域,application 應用域)物件的方式
- 2. Servlet中的三個域物件
- 3. 準備工作
- 3.1 建立模組,新增依賴
- 3.2 新增 web 支援
- 3.3 編寫 web.xml 檔案
- 3.4 建立 IndexController 類
- 3.5 編寫 springmvc.xml
- 3.6 編寫 index.html 檔案檢視
- 3.7 部署測試
- 4. Spring MVC 獲取 request 請求域物件的五種方式
- 4.1 第一種方式:使用原生Servlet API方式 獲取到 request 請求域,同時獲取到請求域當中對應的內容
- 4.2 第二種方式:使用 Model 介面 獲取到 request 請求域,同時獲取到請求域當中對應的內容
- 4.3 第三種方式:使用Map介面 獲取到 request 請求域,同時獲取到請求域當中對應的內容
- 4.4 第四種方式:使用 ModelMap 類 獲取到 request 請求域,同時獲取到請求域當中對應的內容
- 4.5 補充:Model、Map、ModelMap的關係
- 4.6 第五種方式:使用 ModelAndView 類獲取到 request 請求域,同時獲取到請求域當中對應的內容
- 4.7 補充:ModelAndView 原始碼分析
- 5. Spring MVC 獲取 session 會話域物件的二種方式
- 5.1 第一種方式:使用原生Servlet API 獲取到 session 會話域,同時獲取到 session 會話域當中的資訊
- 5.2 第二種方式:使用 @SessionAttributes 註解 獲取到 session 會話域,同時獲取到 session 會話域當中的資訊
- 6. Spring MVC 獲取 application 應用域物件的方式
- 7. 總結:
- 8. 最後:
2. Servlet中的三個域物件
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失效,會話結束。使用會話域的業務場景:
- 在 A 資源中透過重定向(重定向是一次新的請求)的方式轉到 B 資源,因為是重定向,因此從 A到 B 是兩次請求,如果想讓 A 資源和 B 資源共享同一個資料,可以將資料儲存到 session域中
- 登入成功後儲存使用者的登入狀態
application
介面名:ServletContext
簡稱:application
application物件代表了整個 web 應用,伺服器啟動的建立,伺服器關閉時銷燬,對於一個 web 應用來說,application 物件只有一個。使用應用域的業務場景:記錄網站的線上人數。
3. 準備工作
3.1 建立模組,新增依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.rainbowsea</groupId>
<artifactId>springmvc-004-blog</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<!--springmvc依賴-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>6.1.4</version>
</dependency>
<!--logback依賴-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.3</version>
</dependency>
<!--servlet依賴-->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
<!--thymeleaf和spring6整合的依賴-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring6</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
</dependencies>
</project>
3.2 新增 web 支援
先在 main 目錄下,新增名為 webapp
的目錄(資料夾),只能是這個 webapp 目錄名,不可以是其他的。
3.3 編寫 web.xml 檔案
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<!--前端控制器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--透過初始化引數來指定springmvc配置檔案的路徑和名字。-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--在伺服器啟動的時候初始化DispatcherServlet,提高第一次訪問的效率-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- 除了 jsp 其他的路徑都被獲取到-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3.4 建立 IndexController 類
建立 IndexController 類作為 首頁來使用
package com.rainbowsea.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller // 交給 Spring IOC 容器管理
public class IndexController {
@RequestMapping("/")
public String index() {
return "index";
}
}
3.5 編寫 springmvc.xml
在 springmvc.xml 當中配置兩個資訊:
- 元件掃描
- 檢視解析器
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- 元件掃描-->
<context:component-scan base-package="com.rainbowsea.springmvc.controller"></context:component-scan>
<!-- 檢視解析器-->
<bean id="thymeleafViewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
<!--作用於檢視渲染的過程中,可以設定檢視渲染後輸出時採用的編碼字符集-->
<property name="characterEncoding" value="UTF-8"/>
<!--如果配置多個檢視解析器,它來決定優先使用哪個檢視解析器,它的值越小優先順序越高-->
<property name="order" value="1"/>
<!--當 ThymeleafViewResolver 渲染模板時,會使用該模板引擎來解析、編譯和渲染模板-->
<property name="templateEngine">
<bean class="org.thymeleaf.spring6.SpringTemplateEngine">
<!--用於指定 Thymeleaf 模板引擎使用的模板解析器。模板解析器負責根據模板位置、模板資源名稱、檔案編碼等資訊,載入模板並對其進行解析-->
<property name="templateResolver">
<bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver">
<!--設定模板檔案的位置(字首)-->
<property name="prefix" value="/WEB-INF/templates/"/>
<!--設定模板檔案字尾(字尾),Thymeleaf副檔名不一定是html,也可以是其他,例如txt,大部分都是html-->
<property name="suffix" value=".html"/>
<!--設定模板型別,例如:HTML,TEXT,JAVASCRIPT,CSS等-->
<property name="templateMode" value="HTML"/>
<!--用於模板檔案在讀取和解析過程中採用的編碼字符集-->
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
</beans>
3.6 編寫 index.html 檔案檢視
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>測試三個物件</title>
</head>
<body>
<h1>測試三個域物件</h1>
<hr>
<h2>測試 request 域物件</h2>
</body>
</html>
3.7 部署測試
4. Spring MVC 獲取 request 請求域物件的五種方式
在SpringMVC中,在request域中共享資料有以下五種方式:
- 使用原生Servlet API方式。
- 使用Model介面。
- 使用Map介面。
- 使用ModelMap類。
- 使用ModelAndView類。
4.1 第一種方式:使用原生Servlet API方式 獲取到 request 請求域,同時獲取到請求域當中對應的內容
第一種方式: 在Spring MVC 中使用原生的 Servlet API 可以完成 request 域資料共享
,在處理器方法上新增 HttpServletRequest 引數即可。
將 HttpServletRequest 作為引數,定義到方法上,Spring MVC 框架會自動從 Tomcat 伺服器當中獲取到這個 HttpServletRequest 物件的值,然後,傳遞給這個方法的 HttpServletRequest 引數值上,完成賦值。
建立一個 RequestScopeTestController 類,注意要交給 Spring IOC 容器管理起來
package com.rainbowsea.springmvc.controller;
import jakarta.servlet.http.HttpServletRequest;
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 java.util.Map;
@Controller // 交給Spring IOC 容器管理
public class RequestScopeTestController {
// request 請求域
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request) {
// 將共享的資料儲存到 request域當中
// 跳轉檢視,在檢視頁面將request域中的資料取出,這樣就完成了,Controller和View在同一個請求當中兩個元件之間的資料共享
// 將共享的資料儲存到request域當中
request.setAttribute("testRequestScope", "在SpringMVC當中使用原生Servlet API 完成 request域的資料共享");
System.out.println(request);
System.out.println(request.getClass().getName());
// 跳轉檢視,在檢視頁面將 request 域中的資料取出來,這樣就完成了,Controller 和 View 在同
// 一個請求當中兩個元件之間資料的共享
// 注意:這個是跳轉,預設情況下是,轉發的方式,(轉發 forward 是一次請求)
// 這個返回的是一個邏輯檢視名稱,經過檢視解析器解析,變成物理檢視名稱,/WEB-INF/templates/ok.html
return "ok";
}
}
index頁面超連結的編寫:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>測試三個物件</title>
</head>
<body>
<h1>測試三個域物件</h1>
<hr>
<h2>測試 request 域物件</h2>
<a th:href="@{/testServletAPI}">測試在SpringMVC當中使用原生 Servlet API 完成 request 域的資料共享</a>
<br>
</body>
</html>
ok 頁面獲取 request 請求域的展示
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>測試三個物件</title>
</head>
<body>
<h1>測試三個域物件</h1>
<hr>
<h2>測試 request 域物件</h2>
<a th:href="@{/testServletAPI}">測試在SpringMVC當中使用原生 Servlet API 完成 request 域的資料共享</a>
<br>
</body>
</html>
測試結果:
這種方式當然可以,用 SpringMVC 框架,不建議使用原生 Servlet API
4.2 第二種方式:使用 Model 介面 獲取到 request 請求域,同時獲取到請求域當中對應的內容
import jakarta.servlet.http.HttpServletRequest;
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 java.util.Map;
@Controller // 交給Spring IOC 容器管理
public class RequestScopeTestController {
@RequestMapping(value = "/testModel")
public String testModel(Model model) {
// 向 request 域當中繫結資料
model.addAttribute("testRequestScope", "在SpringMVC 當中使用 Model 介面完成 request 域資料共享");
System.out.println(model);
System.out.println(model.getClass().getName());
// 轉發
return "ok";
}
}
index 頁面超連結的編寫:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>測試三個物件</title>
</head>
<body>
<h1>測試三個域物件</h1>
<hr>
<h2>測試 request 域物件</h2>
<a th:href="@{/testServletAPI}">測試在SpringMVC當中使用原生 Servlet API 完成 request 域的資料共享</a>
<br>
<a th:href="@{/testModel}">測試在 Spring MVC 當中使用 Model 介面完成 request 域資料共享</a>
<br>
</body>
</html>
ok 頁面獲取 request 請求域的展示
<!DOCTYPE html>
<html lang="en" xmlns:th="http//www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>OK</title>
</head>
<body>
<div th:text="${testRequestScope}"></div>
</body>
</html>
啟動 Tomcat 伺服器測試結果:
4.3 第三種方式:使用Map介面 獲取到 request 請求域,同時獲取到請求域當中對應的內容
import jakarta.servlet.http.HttpServletRequest;
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 java.util.Map;
@Controller // 交給Spring IOC 容器管理
public class RequestScopeTestController {
@RequestMapping(value = "/testMap")
public String testMap(Map<String, Object> map) {
// 向 request 域當中的儲存資料
map.put("testRequestScope", "在Spring MVC 當中使用 Map介面完成 request 域資料共享");
System.out.println(map);
System.out.println(map.getClass().getName());
// 轉發
return "ok";
}
}
index 頁面超連結的編寫:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>測試三個物件</title>
</head>
<body>
<h1>測試三個域物件</h1>
<hr>
<h2>測試 request 域物件</h2>
<a th:href="@{/testServletAPI}">測試在SpringMVC當中使用原生 Servlet API 完成 request 域的資料共享</a>
<br>
<a th:href="@{/testModel}">測試在 Spring MVC 當中使用 Model 介面完成 request 域資料共享</a>
<br>
<a th:href="@{/testMap}">測試在Spring MVC 當中使用 Map 介面完成 request 域資料共享</a>
<br>
</body>
</html>
ok 頁面獲取 request 請求域的展示 保持不變
啟動 Tomcat 伺服器測試結果:
4.4 第四種方式:使用 ModelMap 類 獲取到 request 請求域,同時獲取到請求域當中對應的內容
import jakarta.servlet.http.HttpServletRequest;
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 java.util.Map;
@Controller // 交給Spring IOC 容器管理
public class RequestScopeTestController {
@RequestMapping(value = "/testModelMap")
public String testModelMap(ModelMap modelMap) {
// 向 request 域當中儲存資料
modelMap.addAttribute("testRequestScope", "在Spring MVC 當中 ModelMap類完成request 域資料共享");
System.out.println(modelMap);
System.out.println(modelMap.getClass().getName());
return "ok";
}
}
index 頁面超連結的編寫:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>測試三個物件</title>
</head>
<body>
<h1>測試三個域物件</h1>
<hr>
<h2>測試 request 域物件</h2>
<a th:href="@{/testServletAPI}">測試在SpringMVC當中使用原生 Servlet API 完成 request 域的資料共享</a>
<br>
<a th:href="@{/testModel}">測試在 Spring MVC 當中使用 Model 介面完成 request 域資料共享</a>
<br>
<a th:href="@{/testMap}">測試在Spring MVC 當中使用 Map 介面完成 request 域資料共享</a>
<br>
<a th:href="@{/testModelMap}">測試在Spring MVC當中使用 ModelMap 類完成 request 域資料共享</a>
<br>
</body>
</html>
ok 頁面獲取 request 請求域的展示 保持不變
啟動 Tomcat 伺服器測試結果:
4.5 補充:Model、Map、ModelMap的關係
可以在以上Model、Map、ModelMap的測試程式中將其輸出,看看輸出什麼:
看不出來什麼區別,從輸出結果上可以看到都是一樣的。
可以將其執行時類名輸出:
透過輸出結果可以看出,無論是Model、Map還是ModelMap,底層例項化的物件都是:BindingAwareModelMap。
可以檢視 BindingAwareModelMap的繼承結構:
透過繼承結構可以看出:BindingAwareModelMap繼承了ModelMap,而ModelMap又實現了Map介面。
另外,請看以下原始碼:
可以看出ModelMap又實現了Model介面。因此表面上是採用了不同方式,底層本質上是相同的。
SpringMVC之所以提供了這些方式,目的就是方便程式設計師的使用,提供了多樣化的方式,可見它的重要性。
4.6 第五種方式:使用 ModelAndView 類獲取到 request 請求域,同時獲取到請求域當中對應的內容
在 Spring MVC 框架中為了更好的體現 MVC 架構模式,提供了一個類:ModelAndView。
這個類的例項封裝了 Model 和 View 。也就是說 這個類封裝業務處理之後的資料,也體現了跳轉到哪個檢視。使用它也可以完成 request 域資料共享。
使用這種方式的注意事項:
- 方法的返回值型別不是 String 了,而是 ModelAndView 物件
- ModelAndView 不是出現在方法的引數位置上了,而是在方法體中 new 出來的
- 需要呼叫
addObject()
向域中儲存資料- 需要呼叫
setViewName()
設定檢視的名字- 最後需要將 ModelAndView 作為引數,返回。
import jakarta.servlet.http.HttpServletRequest;
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 java.util.Map;
@Controller // 交給Spring IOC 容器管理
public class RequestScopeTestController {
@RequestMapping(value = "/testModelAndView")
public ModelAndView testModelAndView() {
// 建立模型檢視物件
ModelAndView modelAndView = new ModelAndView();
// 給模型檢視物件繫結資料
modelAndView.addObject("testRequestScope", "在SpringMVC當中使用 ModelAndView 類完成 request 域資料共享");
// 給模型檢視物件 繫結檢視(繫結邏輯檢視名稱)
modelAndView.setViewName("ok");
// 返回模型檢視物件
return modelAndView;
}
}
index頁面超連結的編寫:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>測試三個物件</title>
</head>
<body>
<h1>測試三個域物件</h1>
<hr>
<h2>測試 request 域物件</h2>
<a th:href="@{/testServletAPI}">測試在SpringMVC當中使用原生 Servlet API 完成 request 域的資料共享</a>
<br>
<a th:href="@{/testModel}">測試在 Spring MVC 當中使用 Model 介面完成 request 域資料共享</a>
<br>
<a th:href="@{/testMap}">測試在Spring MVC 當中使用 Map 介面完成 request 域資料共享</a>
<br>
<a th:href="@{/testModelMap}">測試在Spring MVC當中使用 ModelMap 類完成 request 域資料共享</a>
<br>
<a th:href="@{/testModelAndView}">測試在Spring MVC當中使用 ModelAndView 類完成 request 域資料共享</a>
<br>
</body>
</html>
ok 頁面獲取 request 請求域的展示的編寫:
<!DOCTYPE html>
<html lang="en" xmlns:th="http//www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>OK</title>
</head>
<body>
<div th:text="${testRequestScope}"></div>
</body>
</html>
啟動 Tomcat 伺服器測試結果:
4.7 補充:ModelAndView 原始碼分析
以上我們透過了五種方式完成了request域資料共享,包括:原生 Servlet API,Model、Map、ModelMap、ModelAndView
其中後四種:Model、Map、ModelMap、ModelAndView。
這四種方式在底層DispatcherServlet呼叫我們的Controller之後,返回的物件都是ModelAndView,
這個可以透過原始碼進行分析。
在以上四種方式中,拿Model舉例,新增斷點進行除錯:
啟動伺服器,傳送請求,走到斷點:
檢視VM Stack資訊:
檢視 DispatcherServlet 的1089行,原始碼如下:
可以看到這裡,無論你使用哪種方式,最終都要返回一個ModelAndView物件。
對於
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
處理器方法來說,不管你使用的引數是 Model介面,還是Map介面,還是ModelMap類,還是ModelAndView類,最終處理器方法執行結束之前
返回的都是 ModelAndView物件,這個返回的ModelAndView物件給DispatcherServlet類了
當請求路徑不是JSP的時候,都會走前端控制器 DispatcherServlet
DispatcherServlet 中有一個核心方法 doDispatch(),這個方法用來透過請求路徑找到對應的處理器方法
然後呼叫處理器方法,處理器方法返回一個邏輯檢視名稱(可能也會直接返回一個ModelAndView物件)
,返回給DispatcherServlet
提醒:大家可以透過以下斷點除錯方式,採用一級一級返回,最終可以看到都會返回ModelAndView物件。
5. Spring MVC 獲取 session 會話域物件的二種方式
在SpringMVC中使用session域共享資料,實現方式有多種,其中比較常見的兩種方式:
- 使用原生Servlet API
- 使用SessionAttributes註解
5.1 第一種方式:使用原生Servlet API 獲取到 session 會話域,同時獲取到 session 會話域當中的資訊
使用原生Servlet API ,就是將 HttpSession 作為方法的引數形式,Spring MVC 會自動獲取到 Tomcat 伺服器當中的 HttpSession 物件,賦值到這個方法的對應的 HttpSession 引數上。
建立:SessionScopeTestController 類
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 // 交給 Spring IOC 容器管理
public class SessionScopeTestController {
@RequestMapping("/testSessionServletAPI")
public String testServletAPI(HttpSession session) {
// 處理核心業務...
//將資料儲存到 Session中
session.setAttribute("testSessionScope","在Spring MVC 當中使用原生 Servlet API 完成 session 域資料共享");
// 返回邏輯檢視(這是一個轉發的行為)
return "ok";
}
}
index 頁面超連結的編寫:
ok 頁面獲取 request 請求域的展示的編寫
<!DOCTYPE html>
<html lang="en" xmlns:th="http//www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>OK</title>
</head>
<body>
<div th:text="${session.testSessionScope}"></div>
</body>
</html>
啟動 Tomcat 伺服器測試結果:
5.2 第二種方式:使用 @SessionAttributes 註解 獲取到 session 會話域,同時獲取到 session 會話域當中的資訊
使用 @SessionAttributes 註解標註 Controller:
@SessionAttributes(value = {"x","y","testSessionScope"}) // 標註 x 和 y 都是存放到 session 域中,而不是 request域
**注意:@SessionAttributes 註解使用在Controller類上。標註了當 key是 x 或者 y 時,該(x 或 y)的資料將被儲存到會話 session域當中中。而如果沒有 SessionAttributes註解,預設儲存到 request域中。 **
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;
@SessionAttributes(value = {"x","y","testSessionScope"}) // 標註 x 和 y 都是存放到 session 域中,而不是 request域
@Controller // 交給 Spring IOC 容器管理
public class SessionScopeTestController {
@RequestMapping(value = "/testSessionAttributes")
public String testSessionAttributes(ModelMap modelMap) {
// 處理業務
// 將資料儲存到 Session域當中
modelMap.addAttribute("testSessionScope","在Spring MVC 當中使用@SessionAttributes 註解完成 session 域資料共享");
modelMap.addAttribute("x","李華");
modelMap.addAttribute("y","小紅");
return "ok";
}
}
index 頁面超連結的編寫:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>測試三個物件</title>
</head>
<body>
<h1>測試三個域物件</h1>
<hr>
<h2>測試Session域物件</h2>
<a th:href="@{/testSessionAttributes}">測試在Spring MVC 當中使用 @SessionAttributes 註解完成 session域資料共享</a>
<br>
</body>
</html>
ok 頁面獲取 request 請求域的展示的編寫:
<!DOCTYPE html>
<html lang="en" xmlns:th="http//www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>OK</title>
</head>
<body>
<div th:text="${session.testSessionScope}"></div>
<div th:text="${session.x}"></div>
<div th:text="${session.y}"></div>
</body>
</html>
啟動 Tomcat 伺服器測試結果:
6. Spring MVC 獲取 application 應用域物件的方式
在SpringMVC實現application域資料共享,最常見的方案就是直接使用Servlet API了:
這個 application 域使用較少,如果使用的話,一般是採用 ServletAPI的方式使用
建立:ApplicationScopeTestController 類
將 HttpServletRequest 作為引數,定義到方法上,Spring MVC 框架會自動從 Tomcat 伺服器當中獲取到這個 HttpServletRequest 物件的值,然後,傳遞給這個方法的 HttpServletRequest 引數值上,完成賦值。
package com.rainbowsea.springmvc.controller;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller // 交給 Spring IOC 容器管理
public class ApplicationScopeTestController {
@RequestMapping("/testApplicationScope")
public String testApplicationScope(HttpServletRequest request) {
// 將資料儲存到application域當中
// 獲取application物件,其實就是獲取 ServletContext物件
// 怎麼獲取 ServletContext物件/透過 request,透過 session都可以用
ServletContext application = request.getServletContext();
application.setAttribute("testApplicationScope", "在Spring MVC 中使用 Servlet API中實現application域共享");
return "ok";
}
}
index 頁面超連結的編寫:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>測試三個物件</title>
</head>
<body>
<h1>測試三個域物件</h1>
<hr>
<h2>測試Application應用域物件</h2>
<a th:href="@{/testApplicationScope}">測試在Spring MVC 當中使用 Servlet API 實現application域資料共享</a>
<br>
</body>
</html>
ok 頁面獲取 request 請求域的展示的編寫
啟動 Tomcat 伺服器測試結果:
7. 總結:
三個域:request 請求域,session 會話域,application 應用域
三者域的使用,從最小範圍的域,來判斷使用,可以用範圍更小的域,就用範圍更小的域來解決問題,傳資料資源。如果域的範圍不夠,就一點的擴大。
在SpringMVC中,在request域中共享資料有以下五種方式:
- 使用原生Servlet API方式。
- 使用Model介面。
- 使用Map介面。
- 使用ModelMap類。
- 使用ModelAndView類。
在SpringMVC中使用session域共享資料,實現方式有多種,其中比較常見的兩種方式:
- 使用原生Servlet API
- 使用SessionAttributes註解
Spring MVC 獲取 application 應用域物件的方式
8. 最後:
“在這個最後的篇章中,我要表達我對每一位讀者的感激之情。你們的關注和回覆是我創作的動力源泉,我從你們身上吸取了無盡的靈感與勇氣。我會將你們的鼓勵留在心底,繼續在其他的領域奮鬥。感謝你們,我們總會在某個時刻再次相遇。”