日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

SpringMVC视图及如何在域对象中共享数据

發布時間:2024/1/8 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringMVC视图及如何在域对象中共享数据 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

SpringMVC

  • 回顧原生Servlet 獲取請求參數
    • 通過 Servlet API 獲取
      • 案例
    • 通過控制器方法的形參獲取請求參數
      • 設置字符編碼格式
        • CharacterEncodingFilter 部分源碼
      • 案例
        • 無同名請求參數
        • 有同名請求參數
    • @RequestParam 注解獲取請求參數
      • 案例
    • @RequestHeader 注解
      • 案例
    • @CookieValue
      • 案例
    • 通過 POJO 獲取請求參數
      • 案例
  • 域對象共享數據
    • 使用 ServletAPI 向 request 域對象共享數據
    • 使用ModelAndView向request域對象共享數據
    • 使用 Model 向 request 域對象共享數據
    • 使用 Map 向 request 域對象共享數據
    • 使用 ModelMap 向 request 域對象共享數據
    • Model、ModelMap、Map的關系
    • 使用 ServletAPI 向 session 域共享數據
    • 使用ServletAPI向application域共享數據
  • 四大作用域說明
    • application 作用域
    • session 作用域
      • 了解
      • 刪除 session 的三種方式
      • 注意
    • request 作用域
    • page 作用域
  • SpringMVC 的視圖
    • ThymeleafView
      • 案例
      • 原理分析
    • 轉發視圖
      • 案例
      • 原理分析
    • 重定向視圖
      • 案例
      • 原理分析
    • 轉發與重定向(理解)
      • 轉發
      • 重定向
    • SpringMVC 視圖控制器(view-controller)
    • SpringMVC 視圖解析器(InternalResourceViewResolver)

回顧原生Servlet 獲取請求參數

通過 Servlet API 獲取

  • 將 HttpServletRequest 作為控制器方法的形參,此時 HttpServletRequest 類型的參數表示封裝了當前請求的請求報文的對象。

    一個 HTTP 請求報文由請求行(request line)、請求頭部(header)、空行和請求數據 4 個部分組成

案例

  • 創建 test_param.html 頁面用來測試獲取請求參數的效果

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>測試請求參數</title> </head> <body><h1>測試請求參數</h1><a th:href="@{/testServletAPI(name='tom', age=18)}">測試使用ServletAPI獲取請求參數</a><br/> </body> </html>
  • 創建 Controller,并編寫對應控制器方法

    package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest;/*** @ClassName ParamController* @Description: 測試獲取請求參數的功能* @Author Laoyang* @Date 2022/1/7 11:13*/ @Controller public class ParamController {/*** 跳轉至 test_param 頁面*/@RequestMapping("/param")public String doTestParam() {return "test_param";}/*** 通過 ServletAPI 獲取請求參數* 形參位置的 request 表示當前請求(通過它可以獲取到當前請求中的數據)* > 實際開發中 request 用的比較少,一般都是用注解獲取*/@RequestMapping("/testServletAPI")public String testServletAPI(HttpServletRequest request){String name = request.getParameter("name");String age = request.getParameter("age");System.out.println(name + "--->" + age); // tom--->18return "success";} }
  • 啟動Tomcat測試效果

    • 瀏覽器效果

    • 控制臺效果

通過控制器方法的形參獲取請求參數

  • 在控制器方法的形參位置,設置和請求參數同名的形參,當瀏覽器發送請求,匹配到請求映射時,在 DispatcherServlet 中就會將請求參數賦值給相應的形參

設置字符編碼格式

  • 為什么要設置?

    如果我們不設置字符編碼的話,那么表單提交中文數據之后,就會導致亂碼,所以這里先設置對應的字符編碼,這樣就不用擔心后面的測試會出現亂碼的問題了。

在 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"><!-- 設置字符編碼格式 --><filter><filter-name>encoding-filter</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>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>encoding-filter</filter-name><url-pattern>/*</url-pattern></filter-mapping> </web-app>

Ps:雖然我這里只寫了設置字符編碼的代碼,但是之前的配置也是要加上的(比如注冊前端控制器那些配置),我這里為了簡潔,就不全部展示出來了。

CharacterEncodingFilter 部分源碼

public class CharacterEncodingFilter extends OncePerRequestFilter {// 字符編碼格式@Nullableprivate String encoding;// 是否強制使用手動設置的編碼格式private boolean forceRequestEncoding = false;private boolean forceResponseEncoding = false;public void setForceEncoding(boolean forceEncoding) {this.forceRequestEncoding = forceEncoding;this.forceResponseEncoding = forceEncoding;}@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {String encoding = getEncoding();if (encoding != null) {// 如果 forceRequestEncoding 不為false 或者還沒有設置 request 的字符編碼,那么就設置request的字符編碼if (isForceRequestEncoding() || request.getCharacterEncoding() == null) {request.setCharacterEncoding(encoding);}// 如果 forceResponseEncoding 不為false,就設置 response 的字符編碼if (isForceResponseEncoding()) {response.setCharacterEncoding(encoding);}}// 如果 encoding 沒有配置,則使用默認的編碼格式filterChain.doFilter(request, response);} }

案例

無同名請求參數

  • 在 test_param.html 頁面編寫超鏈接

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>測試請求參數</title> </head> <body><h1>測試請求參數</h1><!-- 通過控制器方法的形參獲取請求參數 --><a th:href="@{/parameter(name='tom', age=18)}">通過控制器方法的形參獲取請求參數</a><br/> </body> </html>
  • 編寫對應控制器方法

    package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.List;@Controller public class ParamController {/*** 通過控制器方法的形參獲取請求參數(無重名屬性寫法)* 如果沒有重名的請求參數傳過來,那么只需要將傳過來的請求參數名和控制器方法中的參數名保持一致即可*/@RequestMapping("/parameter")public String doParameter(String name, Integer age) {System.out.println(name + "--->" + age); // tom--->18return "success";} }
  • 啟動Tomcat查看效果

    控制臺打印:admin--->12345--->籃球,足球

有同名請求參數

  • 在 test_param.html 頁面編寫表單

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>測試請求參數</title> </head> <body><h1>測試請求參數</h1><form method="get" th:action="@{/parameter2}">用戶名:<input name="username" type="text"><br/>密碼:<input name="password" type="text"><br/>愛好:<input name="hobby" type="checkbox" value="籃球">籃球<input name="hobby" type="checkbox" value="足球">足球<input name="hobby" type="checkbox" value="羽毛球">羽毛球<br/><input type="submit" value="提交測試"></form> </body> </html>
  • 編寫對應控制器方法

    package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.List;@Controller public class ParamController {/*** 通過控制器方法的形參獲取請求參數(無重名屬性寫法)* 如果有多個重名的請求參數傳過來(比如表單中的復選框),則可以使用下面的幾種方式接收:* 1、可以使用請求參數名與控制參數名相同的方式進行接收(String hobby),多個值之間默認會使用逗號分隔(a,b,c)* 2、可以使用一個數組進行接收(String[] hobby)* > 大家可根據自己的需求進行使用*/@RequestMapping("/parameter2")public String doParameter2(String username, String password, String[] hobby) {// System.out.println(username + "--->" + password + "--->" + hobby);System.out.println(username + "--->" + password);System.out.println(Arrays.toString(hobby));return "success";} }
  • 啟動Tomcat查看效果

    效果和無同名參數是一樣的,都可以獲取到對應的請求參數

@RequestParam 注解獲取請求參數

  • @RequestParam 是將請求參數和控制器方法的形參創建映射關系

  • @RequestParam 注解一共有三個屬性

    • value:指定為形參賦值的請求參數的參數名

    • required:設置是否必須傳輸此請求參數,默認值為 true

      若設置為true時,則當前請求必須傳輸value所指定的請求參數,若沒有傳輸該請求參數,且沒有設置 defaultValue 屬性,則頁面報錯 400:Required String parameter 'xxx' is not present;若設置為 false,則當前請求不是必須傳輸 value 所指定的請求參數,若沒有傳輸,則注解所標識的形參的值為 null

    • defaultValue:不管 required 屬性值為 true 或 false,當 value 所指定的請求參數沒有傳輸或傳輸的值為 “”(空字符串)時,則使用默認值為形參賦值

案例

  • 在 test_param.html 頁面編寫表單

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>測試請求參數</title> </head> <body><h1>測試請求參數</h1><!-- 使用注解方式獲取請求參數 --><form method="get" th:action="@{/parameter3}"><!-- 用戶名設置為 user_name,這樣后端的 username 形參就接收不到了這個時候就需要使用 @RequestParam 注解進行獲取 -->用戶名:<input name="user_name" type="text"><br/>密碼:<input name="password" type="text"><br/>愛好:<input name="hobby" type="checkbox" value="籃球">籃球<input name="hobby" type="checkbox" value="足球">足球<input name="hobby" type="checkbox" value="羽毛球">羽毛球<br/><input type="submit" value="提交測試"></form> </body> </html>
  • 編寫對應控制器方法

    package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.List;@Controller public class ParamController {@RequestMapping("/parameter3")public String doParameter3(String username,String password,String[] hobby) { // System.out.println(username + "--->" + password + "--->" + hobby);System.out.println(username + "--->" + password);System.out.println(Arrays.toString(hobby));return "success";} }

    為了能夠讓大家看到更好的效果,我這里先不加 @RequestParam 注解

  • 啟動Tomcat查看效果

    瀏覽器中的效果基本沒什么問題,但是控制臺中打印的效果就是:null--->12345--->籃球,足球

    雖然瀏覽器發送請求的時候帶了 user_name,但是控制器方法中并沒有可以接收這個值的參數,所以最后得到的值就是 null

  • 使用 @RequestParam 注解獲取請求參數

    package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.List;@Controller public class ParamController {/*** 使用 @RequestParam 注解獲取請求參數* 參數說明:* name:請求參數名稱* value:請求參數名稱(這個參數用的比 name 要多,但是效果是一樣的)* required:默認為true,表示是否必須傳輸 value或name 對應的請求參數* (比如這里對應的請求參數為 user_name,如果我們在請求映射的時候發現請求參數中并沒有 user_name 這個值,那么就會報 400)* defaultValue:默認值,如果沒有傳輸 value或name 對應的請求參數,則會使用我們設置的默認值* 如果傳輸了對應的請求參數,則使用傳輸過來的值* 該屬性會將 required 值設置為 false*/@RequestMapping("/parameter3")public String doParameter3(@RequestParam(value = "user_name", defaultValue = "haha") String username,String password,String[] hobby) { // System.out.println(username + "--->" + password + "--->" + hobby);System.out.println(username + "--->" + password);System.out.println(Arrays.toString(hobby));return "success";} }

    大家可以結合注釋中的屬性說明,進行設置,然后測試對應的效果,我這里就不一 一展示了

  • 再次測試

    控制臺打印:admin--->123456--->籃球,足球(具體打印的數據就是這些,只是格式不同罷了,大家不要太較真),因為我們還設置了默認值,所以如果在表單提交的時候 user_name 為空,那么最后打印的就是 haha--->123456--->籃球,足球,有興趣的話可以測試一下

@RequestHeader 注解

  • @RequestHeader 是將請求頭信息和控制器方法的形參創建映射關系
  • @RequestHeader 注解一共有三個屬性:value、required、defaultValue,用法同 @RequestParam

案例

  • 在 test_param.html 頁面編寫超鏈接

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>測試請求參數</title> </head> <body><h1>測試請求參數</h1><!-- 使用 @RequestHeader 注解獲取請求頭信息 --><a th:href="@{/header}">測試@RequestHeader注解獲取請求頭信息</a><br/> </body> </html>
  • 編寫對應控制器方法

    package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; import java.util.*;@Controller public class ParamController {/*** 使用 @RequestHeader 注解獲取請求頭信息* 可以使用 Map 獲取到所有的請求頭信息,也可以只獲取請求頭信息中某一個參數* > @RequestHeader 注解的屬性和 @RequestParam 注解的一樣,所以這里就不多說了*/@RequestMapping("/header")public String doHeader(@RequestHeader("Host") String host, @RequestHeader Map<String, String> headers) {for (Map.Entry<String, String> map : headers.entrySet()) {System.out.println(map.getKey() + ":" + map.getValue());}System.out.println("host:" + host);return "success";} }
  • 啟動Tomcat查看效果

    • 瀏覽器就是頁面跳轉成功的效果
    • 主要還是看控制臺打印,大家也可以直接把 Map 設置為返回值,然后把獲取的請求頭存進 Map 中然后進行返回,這樣就可以看到在頁面中看到獲取到的請求頭數據了(也可以直接使用 F12 進行查看)

@CookieValue

  • @CookieValue 是將 cookie 數據和控制器方法的形參創建映射關系
  • @CookieValue 注解一共有三個屬性:value、required、defaultValue,用法同 @RequestParam

案例

  • 在 test_param.html 頁面編寫超鏈接

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>測試請求參數</title> </head> <body><h1>測試請求參數</h1><!-- 使用 @CookieValue 注解獲取 Cookie 信息 --><a th:href="@{/cookie}">測試@CookieValue注解獲取請求頭信息</a><br/> </body> </html>
  • 編寫對應控制器方法

    package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.*;@Controller public class ParamController {/*** 使用 @CookieValue 注解獲取 Cookie 信息* > 注意:每個人的 cookie 可能不太一樣,具體可在瀏覽器 F12 中進行查看*/@RequestMapping("/cookie")public String doCookie(@CookieValue("JSESSIONID") String jsessionid) {System.out.println("---->" + jsessionid);return "success";} }
  • 啟動Tomcat查看效果

    • 主要看控制臺的打印效果,所以這里就不截圖了,大家可自行查看

通過 POJO 獲取請求參數

可以在控制器方法的形參位置設置一個實體類類型的形參,此時若瀏覽器傳輸的請求參數的參數名和實體類中的屬性名一致,那么請求參數就會為此屬性賦值。

案例

  • 編寫對應實體類

    package com.laoyang.mvc.pojo;public class User {private String username;private String password;private String sex;private Integer age;private String email;public User() {}public User(String username, String password, String sex, Integer age, String email) {this.username = username;this.password = password;this.sex = sex;this.age = age;this.email = email;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}@Overridepublic String toString() {return "User{" +"username='" + username + '\'' +", password='" + password + '\'' +", sex='" + sex + '\'' +", age=" + age +", email='" + email + '\'' +'}';} }
  • 在 test_param.html 頁面編寫表單

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>測試請求參數</title> </head> <body><h1>測試請求參數</h1><!-- 通過 POJO 獲取請求參數 --><form th:action="@{/doUser}" method="post">用戶名:<input type="text" name="username"><br/>密碼:<input type="password" name="password"><br/>性別:<input type="radio" name="sex" value=""><input type="radio" name="sex" value=""><br/>年齡:<input type="text" name="age"><br/>郵箱:<input type="text" name="email"><br/><input type="submit" value="測試pojo獲取參數"></form> </body> </html>
  • 編寫對應控制器方法

    package com.laoyang.mvc.controller;import com.laoyang.mvc.pojo.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.*;@Controller public class ParamController {/*** 通過 POJO 獲取請求參數* 在需要傳輸多個請求參數的時候最好就是用這種方式* 如果全部寫在控制器方法的形參中會顯得非常冗余,而且也比較麻煩*/@RequestMapping("/doUser")public String doPojo(User user) {System.out.println(user);return "success";} }
  • 啟動Tomcat查看效果

    此時在瀏覽器輸入完對于的表單數據后,控制器方法中就可以正常拿到對應的參數值,并進行打印(記得一定要配置好編碼格式!)

域對象共享數據

  • 為了整潔,創建一個新的工程來進行演示,和之前一樣的東西:web.xml、spring-mvc.xml、pom.xml

  • HelloController:

    package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;@Controller public class TestController {/*** 跳轉至首頁*/@RequestMapping("/")public String doIndex() {return "index";} }
  • index.html:

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>首頁</title> </head> <body><h1>首頁</h1> </body> </html>

使用 ServletAPI 向 request 域對象共享數據

  • 在 index.html 中編寫超鏈接

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>首頁</title> </head> <body><h1>首頁</h1><!-- 使用 ServletAPI 向 request 域對象共享數據 --> <a th:href="@{/doServletAPI}">使用ServletAPI向request域對象共享數據</a><br/></body> </html>
  • 編寫對應控制器方法

    package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest;@Controller public class ScopeController {/*** 使用ServletAPI向request域對象共享數據*/@RequestMapping("/doServletAPI")public String doRequest(HttpServletRequest request) {request.setAttribute("name", "我是張三!");return "success";} }
  • 創建 success.html 頁面,并獲取域對象

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head><meta charset="UTF-8"><title>測試多種獲取域對象的方式</title> </head> <body><h1>測試多種獲取域對象的方式</h1><p th:text="${name}"></p></body> </html>
  • 啟動Tomcat查看效果

使用ModelAndView向request域對象共享數據

  • 在 index.html 中編寫超鏈接

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>首頁</title> </head> <body><h1>首頁</h1> <!-- 使用 ModelAndView 向 request 域對象共享數據 --> <a th:href="@{/doModelAndView}">使用ModelAndView向request域對象共享數據</a><br/> </body> </html>
  • 編寫對應控制器方法

    package com.laoyang.mvc.controller;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;@Controller public class ScopeController {/*** 使用 ModelAndView 向 request 域對象共享數據*/@RequestMapping("/doModelAndView")public ModelAndView doModelAndView() {ModelAndView modelAndView = new ModelAndView();// 處理模型數據,即向請求域 request 共享數據modelAndView.addObject("modelAndView", "Hello, ModelAndView");// 設置視圖名稱(也就是頁面名稱)modelAndView.setViewName("success");return modelAndView;} }
  • 在 success.html 頁面獲取域對象

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head><meta charset="UTF-8"><title>測試多種獲取域對象的方式</title> </head> <body><h1>測試多種獲取域對象的方式</h1> <!-- 使用 ModelAndView 方式共享的數據 --> <p th:text="${modelAndView}"></p></body> </html>
  • 啟動Tomcat查看效果

使用 Model 向 request 域對象共享數據

  • 在 index.html 中編寫超鏈接

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>首頁</title> </head> <body><h1>首頁</h1><!-- 使用 Model 向 request 域對象共享數據 --> <a th:href="@{/doModel}">使用Model向request域對象共享數據</a><br/></body> </html>
  • 編寫對應控制器方法

    package com.laoyang.mvc.controller;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;@Controller public class ScopeController {/*** 使用 Model 向 request 域對象共享數據*/@RequestMapping("/doModel")public String doModel(Model model) {model.addAttribute("model", "代碼人,代碼魂!");return "success";} }
  • 在 success.html 頁面獲取域對象

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head><meta charset="UTF-8"><title>測試多種獲取域對象的方式</title> </head> <body><h1>測試多種獲取域對象的方式</h1><!-- 使用 Model 方式共享的數據 --> <p th:text="${model}"></p></body> </html>
  • 啟動Tomcat查看效果

使用 Map 向 request 域對象共享數據

  • 在 index.html 中編寫超鏈接

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>首頁</title> </head> <body><h1>首頁</h1><!-- 使用 Map 向 request 域對象共享數據 --> <a th:href="@{/doMap}">使用Map向request域對象共享數據</a><br/></body> </html>
  • 編寫對應控制器方法

    package com.laoyang.mvc.controller;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;@Controller public class ScopeController {/*** 使用 Map 向 request 域對象共享數據*/@RequestMapping("/doMap")public String doMap(Map<String, Object> map) {// map 中添加的每一個數據就是一個共享數據map.put("map", "代碼小白!");return "success";} }
  • 在 success.html 頁面獲取域對象

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head><meta charset="UTF-8"><title>測試多種獲取域對象的方式</title> </head> <body><h1>測試多種獲取域對象的方式</h1><!-- 使用 ModelMap 方式共享的數據 --> <p th:text="${modelMap}"></p> </body> </html>
  • 啟動Tomcat查看效果

使用 ModelMap 向 request 域對象共享數據

  • 在 index.html 中編寫超鏈接

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>首頁</title> </head> <body><h1>首頁</h1><!-- 使用 ModelMap 向 request 域對象共享數據 --> <a th:href="@{/doModelMap}">使用ModelMap向request域對象共享數據</a><br/></body> </html>
  • 編寫對應控制器方法

    package com.laoyang.mvc.controller;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;@Controller public class ScopeController {/*** 使用 ModelMap 向 request 域對象共享數據*/@RequestMapping("/doModelMap")public String doModelMap(ModelMap modelMap) {modelMap.addAttribute("modelMap", "2022必沒bug!!!");return "success";} }
  • 在 success.html 頁面獲取域對象

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head><meta charset="UTF-8"><title>測試多種獲取域對象的方式</title> </head> <body><h1>測試多種獲取域對象的方式</h1> <!-- 使用 ModelMap 方式共享的數據 --> <p th:text="${modelMap}"></p> </body> </html>
  • 啟動Tomcat查看效果

Model、ModelMap、Map的關系

一共有五種共享方式:

  • 第一種:使用 ServletAPI(不建議使用)
  • 第二種:使用 ModelAndView
  • 第三種:使用 Model
  • 第四種:使用 Map
  • 第五種:使用 ModelMap

Model、Map、ModelMap 的關系:

BindingAwareModelMap 以及父級的部分源碼: public class BindingAwareModelMap extends ExtendedModelMap {} public class ExtendedModelMap extends ModelMap implements Model {} public class ModelMap extends LinkedHashMap<String, Object> {}這三個方式都是通過 BindingAwareModelMap 類進行實例化的: 因為 BindingAwareModelMap 繼承了 ExtendedModelMap,而 ExtendedModelMap 繼承了 ModelMap,所以BindingAwareModelMap 可以對 ModelMap 進行實例化 因為 BindingAwareModelMap 繼承了 ExtendedModelMap,而 ExtendedModelMap 實現了 Model,所以BindingAwareModelMap 可以對 Model 進行實例化 因為 BindingAwareModelMap 繼承了 ExtendedModelMap,而 ExtendedModelMap 繼承了 ModelMap,而 ModelMap 又繼承了 LinkedHashMap,所以可以對 Map 進行實例化

使用 ServletAPI 向 session 域共享數據

  • 在 index.html 中編寫超鏈接

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>首頁</title> </head> <body><h1>首頁</h1> <!-- 使用 ServletAPI 向 session 域共享數據 --> <a th:href="@{/doSession}">使用ServletAPI向session域共享數據</a><br/></body> </html>
  • 編寫對應控制器方法

    package com.laoyang.mvc.controller;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 ScopeController {/*** 使用ServletAPI向 Session 域共享數據*/@RequestMapping("/doSession")public String doSession(HttpSession session) {session.setAttribute("servletApi", "這是session數據~");return "success";} }
  • 在 success.html 頁面獲取 session 域對象

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head><meta charset="UTF-8"><title>測試多種獲取域對象的方式</title> </head> <body><h1>測試多種獲取域對象的方式</h1> <!-- 使用 ServletAPI 向 Session域共享的數據 --> <p th:text="${session.servletApi}"></p></body> </html>

    注意:在頁面獲取 session 數據的時候需要使用 “session.屬性” 才可以獲取到對應的值

  • 啟動Tomcat查看效果

使用ServletAPI向application域共享數據

  • 在 index.html 中編寫超鏈接

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>首頁</title> </head> <body><h1>首頁</h1> <!-- 使用 ServletAPI 向 application 域共享數據 --> <a th:href="@{/doApplication}">使用ServletAPI向application域共享數據</a><br/></body> </html>
  • 編寫對應控制器方法

    package com.laoyang.mvc.controller;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.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.Map;@Controller public class ScopeController {/*** 使用ServletAPI向 application 域共享數據*/@RequestMapping("/doApplication")public String doApplication(HttpSession session) {ServletContext application = session.getServletContext();application.setAttribute("applicationScope", "這是application的數據哦!");return "success";} }
  • 在 success.html 頁面獲取 application 域對象

    <!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head><meta charset="UTF-8"><title>測試多種獲取域對象的方式</title> </head> <body><h1>測試多種獲取域對象的方式</h1> <!-- 使用 ServletAPI 向 application域共享的數據 --> <p th:text="${application.applicationScope}"></p> </body> </html>

    調用的方式和 session 的差不多,也是需要使用“”對應的域對象.對應的屬性” 才能獲取到對應的值

  • 啟動Tomcat查看效果

四大作用域說明

application 作用域

  • 如果把變量放到 application 里,就說明它的作用域是 application。

  • 有效范圍:application 的有效范圍是整個應用;整個應用是指從應用啟動,到應用結束。我們沒有說 “從服務器啟動,到服務器關閉”,是因為一個服務器可能部署多個應用,當然你關閉了服務器,就會把上面所有的應用都關閉了。

    application 作用域里的變量,它們的存活時間是最長的,如果不手動刪除,它們就可以一直使用

  • Object getAttribute(String name) //從application中獲取信息;

  • void setAttribute(String name,Object value) //向application作用域中設置信息。

session 作用域

  • 如果把變量放到 session 里,就說明它的作用域是session(session 存放在服務器端的內存中)。
  • 有效范圍:它的有效范圍是當前會話;所謂當前會話,就是指從用戶打開瀏覽器開始,到用戶關閉瀏覽器這中間的過程。
  • Object HttpSession.getAttribute(String name) //從session中獲取信息。
  • void HttpSession.setAttribute(String name,Object value)//向session中保存信息。
  • HttpSessionHttpServletRequest.getSessio() //獲取當前請求所在的session的對象。

了解

  • session 從瀏覽器發出第一個 HTTP 請求即可認為會話開始。但結束就不好判斷了,因為瀏覽器關閉時并不會通知服務器,所以只能通過如下這種方法判斷

    如果一定的時間內客戶端沒有反應,則認為會話結束。

  • Tomcat 的默認值為 120 分鐘,但這個值也可以通過 HttpSession的setMaxInactiveInterval() 方法來設置:

    void setMaxInactiveInterval(int interval)

  • 如果想主動讓會話結束,例如用戶單擊 “注銷” 按鈕的時候,可以使用 HttpSession 的 invalidate() 方法,用于強制結束當前 session

刪除 session 的三種方式

  • Session 超時:超時指的是連續一定時間服務器沒有收到該 Session 所對應客戶端的請求,并且這個時間超過了服務器設置的 Session 超時的最大時間。
  • 程序調用 HttpSession.invalidate()
  • 服務器關閉或服務停止

注意

  • 訪問 *.html 的靜態資源因為不會被編譯為 Servlet,也就不涉及 session 的問題了。
  • 當 JSP 頁面沒有顯式禁止 session 的時候,在打開瀏覽器第一次請求該 jsp 的時候,服務器會自動為其創建一個 session,并賦予它一個 sessionID,發送給客戶端的瀏覽器。
  • 由于 session 會消耗內存資源,因此,如果不打算使用 session,應該在所有的 JSP 中關閉它。
  • session 不會應該瀏覽器的關閉而刪除,只能通過上面說的三種方式刪除。
  • request 作用域

    • request 里的變量可以跨越 forward 前后的兩頁,但是只要刷新頁面,它們就重新計算了。

    • 請求轉發:servlet. getRequestDispatcher("new.jsp").forward(req,resp);

    注意

  • 轉發是服務器行為,而重定向是客戶端行為。
  • 無論在服務器上如何轉發,瀏覽器地址欄中顯示的仍然是最初那個 Servlet 的地址。
  • page 作用域

    • page 對象的作用范圍僅限于用戶請求的當前頁面
    • request 和 page 的生命周期都是短暫的,它們之間的區別:一個 request 可以包含多個 page 頁(include,forward 及 filter)。

    更多可看這位大佬寫的博客:https://m.php.cn/article/418934.html

    SpringMVC 的視圖

    • SpringMVC 中的視圖是 View 接口,視圖的作用:渲染數據,將模型 Model 中的數據展示給用戶 SpringMVC 視圖的種類很多,默認有轉發視圖和重定向視圖
    • 當工程引入 jstl 的依賴,轉發視圖會自動轉換為 JstlView
    • 若使用的視圖技術為 Thymeleaf,在 SpringMVC 的配置文件中配置了 Thymeleaf 的視圖解析器,由此視圖解析器解析之后所得到的是 ThymeleafView

    ThymeleafView

    當控制器方法中所設置的視圖名稱沒有任何前綴時,此時的視圖名稱會被 SpringMVC 配置文件中所配置的視圖解析器解析,視圖名稱拼接視圖前綴和視圖后綴所得到的最終路徑,會通過轉發的方式實現跳轉。

    案例

    • 創建 view.html 頁面,并編寫超鏈接

      <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>視圖測試</title> </head> <body> <h1>SpringMVC視圖</h1> <a th:href="@{/doThymeleafView}">測試ThymeleafView</a><br/> </body> </html>
    • 編寫對應控制器方法

      package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;@Controller public class ViewController {/*** 跳轉至視圖測試頁面*/@RequestMapping("/doView")public String doView() {return "view";}/*** 默認(無前綴)* ThymeleafView 視圖對象*/@RequestMapping("/doThymeleafView")public String doThymeleafView() {return "success";} }
    • 啟動Tomcat查看效果

      • 正常效果就是可以正常訪問到 view 頁面和 success 頁面,這里就不截圖了(localhost:8080/springmvc/doView)
      • 實現原理可看下面的原理分析

    原理分析

    部分源碼:

    public class DispatcherServlet extends FrameworkServlet {protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {ModelAndView mv = null;mv = ha.handle(processedRequest, response, mappedHandler.getHandler());// 處理ModelAndView封裝的模型數據和視圖信息processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}// 處理ModelAndView封裝的模型數據和視圖信息private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,@Nullable Exception exception) throws Exception {if (mv != null && !mv.wasCleared()) {// 如果視圖不為空,則將該視圖進行渲染render(mv, request, response);if (errorView) {WebUtils.clearErrorRequestAttributes(request);}}}// 渲染視圖protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {// 本地化(就是本地的環境,由兩個部分組成,一個是語言碼,一個是國家碼,比如 zh_CH 就表示“中文_中國”)Locale locale =(this.localeResolver != null ? this.localeResolver.resolveLocale(request) : request.getLocale());response.setLocale(locale);View view;// 獲取視圖名稱String viewName = mv.getViewName();if (viewName != null) {/* 根據視圖名稱和ModelAndView中封裝的模型數據獲取到視圖對象因為我們沒有在控制器方法返回的時候設置前綴,所以這里創建的是一個ThymeleafView(視圖對象)> 可簡單理解為:當控制器方法中所設置的視圖名稱沒有任何前綴時,得到的就是ThymeleafView視圖對象*/view = resolveViewName(viewName, mv.getModelInternal(), locale, request);if (view == null) {throw new ServletException("Could not resolve view with name '" + mv.getViewName() +"' in servlet with name '" + getServletName() + "'");}}} }

    注意:以上只是部分源碼解析,如果想要看到更加詳細的,可以自行去源碼中探索!

    轉發視圖

    • SpringMVC 中默認的轉發視圖是 InternalResourceView

    • SpringMVC 中創建轉發視圖的情況

      當控制器方法中所設置的視圖名稱以 “forward:” 為前綴時,就會創建 InternalResourceView 視圖,此時的視圖名稱不會被 SpringMVC 配置文件中所配置的視圖解析器解析,而是會將前綴 “forward:” 去掉,剩余部分作為最終路徑通過轉發的方式實現跳轉。

      例如"forward:/",“forward:/employee”

    案例

    • 在 view.html 中編寫超鏈接

      <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>視圖測試</title> </head> <body> <h1>SpringMVC視圖</h1> <a th:href="@{/doForward}">測試InternalResourceView</a><br/></body> </html>
    • 編寫對應控制器方法

      package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;@Controller public class ViewController {/*** 跳轉至視圖測試頁面*/@RequestMapping("/doView")public String doView() {return "view";}/*** 默認(無前綴)* ThymeleafView 視圖對象*/@RequestMapping("/doThymeleafView")public String doThymeleafView() {return "success";}/*** 轉發視圖(前綴為:“forward:”)* InternalResourceView 視圖對象*/@RequestMapping("/doForward")public String doInternalResourceView() {/*1、使用 forward 為前綴時不能直接訪問具體的頁面(會報404),因為頁面必須通過服務器進行訪問>錯誤寫法:return "forward:success";2、如果想要通過 forward 訪問到具體頁面,可以轉發到一個跳轉到某個頁面的控制器方法(控制器方法設置的請求路徑)中比如:forward:/doThymeleafView3、這里最終頁面顯示的地址是 /doForward,而不是 /doThymeleafView*/return "forward:/doThymeleafView";} }
    • 啟動Tomcat查看效果

      • 正常效果就是可以正常訪問到 view 頁面和 success 頁面,這里就不截圖了

    原理分析

    • 關鍵的一些源碼還是剛才的那些,所以這里就不做記錄了

    重定向視圖

    • SpringMVC 中默認的重定向視圖是 RedirectView

    • 當控制器方法中所設置的視圖名稱以 “redirect:” 為前綴時,創建 RedirectView視圖,此時的視圖名稱不會被 SpringMVC 配置文件中所配置的視圖解析器解析,而是會將前綴 “redirect:” 去掉,剩余部分作為最終路徑通過重定向的方式實現跳轉。

      例如"redirect:/",“redirect:/employee”

    案例

    • 在 view.html 中編寫超鏈接

      <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>視圖測試</title> </head> <body> <h1>SpringMVC視圖</h1> <a th:href="@{/doRedirect}">測試RedirectView</a><br/></body> </html>
    • 編寫對應控制器方法

      package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;@Controller public class ViewController {/*** 跳轉至視圖測試頁面*/@RequestMapping("/doView")public String doView() {return "view";}/*** 默認(無前綴)* ThymeleafView 視圖對象*/@RequestMapping("/doThymeleafView")public String doThymeleafView() {return "success";}/*** 重定向視圖(前綴為:“redirect:”)* RedirectView 視圖對象*/@RequestMapping("/doRedirect")public String doRedirectView() {/*1、使用 redirect 為前綴時不能直接訪問具體的頁面(會報404)>錯誤寫法:return "redirect:success";2、如果想要通過 redirect 訪問到具體頁面,可以轉發到一個跳轉到某個頁面的控制器方法(控制器方法設置的請求路徑)中比如:redirect:/doThymeleafView3、這里最終頁面顯示的地址是 /doThymeleafView,而不是 /doRedirect*/return "redirect:/doThymeleafView";} }
    • 啟動Tomcat查看效果

      • 正常效果就是可以正常訪問到 view 頁面和 success 頁面,這里就不截圖了

    原理分析

    • 關鍵的一些源碼還是剛才的哪些,所以這里就不做記錄了

    轉發與重定向(理解)

    轉發與重定向的作用:在 Servlet 中實現頁面的跳轉

    轉發

    • 概念:由服務器進行的頁面跳轉就被稱為 “轉發”

    • 特點

      • 地址欄不發生變化,顯示的是上一個頁面的地址
      • 請求次數:只有一次請求(就是瀏覽器向服務器發送的那一次請求)
      • 請求域數據不會丟失
      • 根目錄:http://localhost:8080/項目地址/,包含了項目的訪問地址
    • 原生 Servlet 實現轉發使用 request.getRequestDispatcher("/地址").forward(request, response);

    • SpringMVC 使用轉發在返回的地址前使用 redirect: 當做前綴(底層會進行解析,最后得到一個 InternalResourceView 視圖對象)

    重定向

    • 概念:由服務器進行的頁面跳轉就被稱為 “重定向”
    • 特點
      • 地址欄顯示的是新的地址
      • 請求次數:兩次
      • 請求域中的數據會丟失,因為是兩次次請求
      • 根目錄:http://localhost:8080/,沒有項目的訪問地址

    SpringMVC 視圖控制器(view-controller)

    當控制器方法中,僅僅用來實現頁面跳轉,即只需要設置視圖名稱時,可以將處理器方法使用 view-controller標簽進行表示。

    注意

    1、如果不單單是跳轉頁面,而是進行了一定的操作,那么就不要使用 view-controller,因為 view-controller 無法實現對應操作!
    2、在配置文件中配置view-controller之后,會導致 controller 控制器中的所有請求映射失效

    • 注釋掉 index 的請求映射

      package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;@Controller public class TestController {/*** 跳轉至首頁*/ // @RequestMapping("/") // public String doIndex() { // return "index"; // }}
    • 在 spring-mvc.xml 配置文件中使用 view-controller 標簽進行處理

      <?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"xmlns:mvc="http://www.springframework.org/schema/mvc"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 http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 掃描組件 --><context:component-scan base-package="com.laoyang.mvc" /><!-- 配置 Thymeleaf 視圖解析器 --><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"><!-- 視圖前綴 --><property name="prefix" value="/WEB-INF/templates/"/><!-- 視圖后綴 --><property name="suffix" value=".html"/><!-- 模板模型 --><property name="templateMode" value="HTML5"/><!-- 頁面編碼格式 --><property name="characterEncoding" value="UTF-8"/></bean></property></bean></property></bean><!--path:設置處理的請求地址,該路徑是和 @RequestMapping 注解中的地址是一樣的簡單理解:就是把 controller 中用來跳轉頁面的控制器方法寫在了配置文件中view-controller:設置請求地址所對應的視圖名稱注意:1、如果不單單是跳轉頁面,而是進行了一定的操作,那么就不要寫在配置文件中,因為配置文件無法實現對應操作!2、在配置文件中配置view-controller之后,會導致 controller 控制器中的所有請求映射失效--><!-- 訪問方式:http://localhost:8080/springmvc/ --><mvc:view-controller path="/" view-name="index"/><!-- 訪問方式:http://localhost:8080/springmvc/doView --><mvc:view-controller path="/doView" view-name="view"/> </beans>

      為了更好的看懂,我這里還配置了一個跳轉到 view.html 頁面的 view-controller,記得要把對應控制器中的控制器方法注釋掉! 不注釋掉的話可能會出現一些不必要的問題。

    • 啟動Tomcat測試效果

      • 訪問方式:localhost:8080/springmvc/

      • 訪問方式:localhost:8080/springmvc/doView

      • 可以看到,我們在配置文件中配置的路徑是可以正常訪問到對應的頁面的,但是此時會有一個小問題,就是點擊頁面的超鏈接之后會報 404,這是因為 view-controller 標簽會導致所有控制器中的請求映射失效。

    • 解決請求映射失效問題(annotation-driven)

      <?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"xmlns:mvc="http://www.springframework.org/schema/mvc"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 http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 掃描組件 --><context:component-scan base-package="com.laoyang.mvc" /><!-- 配置 Thymeleaf 視圖解析器 --><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"><!-- 視圖前綴 --><property name="prefix" value="/WEB-INF/templates/"/><!-- 視圖后綴 --><property name="suffix" value=".html"/><!-- 模板模型 --><property name="templateMode" value="HTML5"/><!-- 頁面編碼格式 --><property name="characterEncoding" value="UTF-8"/></bean></property></bean></property></bean><!--path:設置處理的請求地址,該路徑是和 @RequestMapping 注解中的地址是一樣的view-controller:設置請求地址所對應的視圖名稱--><!-- 訪問方式:http://localhost:8080/springmvc/ --><mvc:view-controller path="/" view-name="index"/><!-- 訪問方式:http://localhost:8080/springmvc/doView --><mvc:view-controller path="/doView" view-name="view"/><!-- 解決請求映射失效問題:開啟 mvc 的注解驅動 --><mvc:annotation-driven /> </beans>
    • 再次測試

      此時點擊超鏈接就可以正常進行映射了

    SpringMVC 視圖解析器(InternalResourceViewResolver)

    我們上面使用的視圖解析器都是解析 html 頁面的(ThymeleafViewResolver),但如果視圖使用的是 JSP 頁面,那么就需要使用 InternalResourceViewResolver 視圖解析器

    • 創建一個新的項目,然后把 web.xml、pom 依賴復制到這個新項目中

    • 在 resource 目錄下創建并編寫 spring-mvc.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.laoyang.mvc" /><!-- 視圖解析器 --><bean id="resolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/templates/" /><property name="suffix" value=".jsp" /></bean> </beans>
    • 在 webapp 目錄下創建 index.jsp

      • 說明

        Tomcat 的 web.xml 文件中配置了默認歡迎頁(index.html,index.htm,index.jsp);但是在 Tomcat 中,每一個 webapp 目錄下的子目錄都被認為是一個 JSP 站點,所以只能訪問到 index.jsp 歡迎頁

        如果在 webapp 目錄下同時創建了 index.html 和 index.jsp,那么訪問的時候就會報 404,如果只有 index.html,那么啟動后也是會報404,因為訪問不到默認頁

      <%--Created by IntelliJ IDEA.User: LaoyangDate: 2022/1/10Time: 17:15To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head><title>首頁</title> </head> <body><h1>Hello Tom!</h1><!--pageContext.request.contextPath:page域對象中的數據,通過這個域對象可以拿到上下文路徑> 因為 jsp 不會自動給我們加上上下文路徑然后在進行訪問,所以這里我們需要手動添加,并且必須添加為動態的上下文路徑> 如果是配置固定的上下文路徑,那么以后一旦修改,維護起來就很麻煩--><a href="${pageContext.request.contextPath}/doSuccess">訪問 success.jsp 頁面</a> </body> </html>
    • 在 WEB-INF/templates 目錄下創建 success.jsp

      <%--Created by IntelliJ IDEA.User: LaoyangDate: 2022/1/10Time: 17:22To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head><title>主頁面</title> </head> <body><h1>主頁面效果</h1> </body> </html>
    • 編寫對應的控制器方法,實現頁面跳轉

      package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;/*** @ClassName JspController* @Description: JSP 跳轉* @Author Laoyang* @Date 2022/1/10 17:12*/ @Controller public class JspController {@RequestMapping("/doSuccess")public String doSuccess() {// 這里返回的 jsp 頁面會被 spring-mvc.xml 配置文件中的視圖解析器進行解析return "success";} }

    總結

    以上是生活随笔為你收集整理的SpringMVC视图及如何在域对象中共享数据的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。