javascript
SpringMVC视图及如何在域对象中共享数据
SpringMVC
- 回顧原生Servlet 獲取請求參數(shù)
- 通過 Servlet API 獲取
- 案例
- 通過控制器方法的形參獲取請求參數(shù)
- 設(shè)置字符編碼格式
- CharacterEncodingFilter 部分源碼
- 案例
- 無同名請求參數(shù)
- 有同名請求參數(shù)
- @RequestParam 注解獲取請求參數(shù)
- 案例
- @RequestHeader 注解
- 案例
- @CookieValue
- 案例
- 通過 POJO 獲取請求參數(shù)
- 案例
- 域?qū)ο蠊蚕頂?shù)據(jù)
- 使用 ServletAPI 向 request 域?qū)ο蠊蚕頂?shù)據(jù)
- 使用ModelAndView向request域?qū)ο蠊蚕頂?shù)據(jù)
- 使用 Model 向 request 域?qū)ο蠊蚕頂?shù)據(jù)
- 使用 Map 向 request 域?qū)ο蠊蚕頂?shù)據(jù)
- 使用 ModelMap 向 request 域?qū)ο蠊蚕頂?shù)據(jù)
- Model、ModelMap、Map的關(guān)系
- 使用 ServletAPI 向 session 域共享數(shù)據(jù)
- 使用ServletAPI向application域共享數(shù)據(jù)
- 四大作用域說明
- application 作用域
- session 作用域
- 了解
- 刪除 session 的三種方式
- 注意
- request 作用域
- page 作用域
- SpringMVC 的視圖
- ThymeleafView
- 案例
- 原理分析
- 轉(zhuǎn)發(fā)視圖
- 案例
- 原理分析
- 重定向視圖
- 案例
- 原理分析
- 轉(zhuǎn)發(fā)與重定向(理解)
- 轉(zhuǎn)發(fā)
- 重定向
- SpringMVC 視圖控制器(view-controller)
- SpringMVC 視圖解析器(InternalResourceViewResolver)
回顧原生Servlet 獲取請求參數(shù)
通過 Servlet API 獲取
-
將 HttpServletRequest 作為控制器方法的形參,此時 HttpServletRequest 類型的參數(shù)表示封裝了當(dāng)前請求的請求報文的對象。
一個 HTTP 請求報文由請求行(request line)、請求頭部(header)、空行和請求數(shù)據(jù) 4 個部分組成
案例
-
創(chuàng)建 test_param.html 頁面用來測試獲取請求參數(shù)的效果
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>測試請求參數(shù)</title> </head> <body><h1>測試請求參數(shù)</h1><a th:href="@{/testServletAPI(name='tom', age=18)}">測試使用ServletAPI獲取請求參數(shù)</a><br/> </body> </html> -
創(chuàng)建 Controller,并編寫對應(yīng)控制器方法
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: 測試獲取請求參數(shù)的功能* @Author Laoyang* @Date 2022/1/7 11:13*/ @Controller public class ParamController {/*** 跳轉(zhuǎn)至 test_param 頁面*/@RequestMapping("/param")public String doTestParam() {return "test_param";}/*** 通過 ServletAPI 獲取請求參數(shù)* 形參位置的 request 表示當(dāng)前請求(通過它可以獲取到當(dāng)前請求中的數(shù)據(jù))* > 實(shí)際開發(fā)中 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測試效果
-
瀏覽器效果
-
控制臺效果
-
通過控制器方法的形參獲取請求參數(shù)
- 在控制器方法的形參位置,設(shè)置和請求參數(shù)同名的形參,當(dāng)瀏覽器發(fā)送請求,匹配到請求映射時,在 DispatcherServlet 中就會將請求參數(shù)賦值給相應(yīng)的形參
設(shè)置字符編碼格式
-
為什么要設(shè)置?
如果我們不設(shè)置字符編碼的話,那么表單提交中文數(shù)據(jù)之后,就會導(dǎo)致亂碼,所以這里先設(shè)置對應(yīng)的字符編碼,這樣就不用擔(dān)心后面的測試會出現(xiàn)亂碼的問題了。
在 web.xml 文件中設(shè)置字符編碼
<?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"><!-- 設(shè)置字符編碼格式 --><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:雖然我這里只寫了設(shè)置字符編碼的代碼,但是之前的配置也是要加上的(比如注冊前端控制器那些配置),我這里為了簡潔,就不全部展示出來了。
CharacterEncodingFilter 部分源碼
public class CharacterEncodingFilter extends OncePerRequestFilter {// 字符編碼格式@Nullableprivate String encoding;// 是否強(qiáng)制使用手動設(shè)置的編碼格式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 或者還沒有設(shè)置 request 的字符編碼,那么就設(shè)置request的字符編碼if (isForceRequestEncoding() || request.getCharacterEncoding() == null) {request.setCharacterEncoding(encoding);}// 如果 forceResponseEncoding 不為false,就設(shè)置 response 的字符編碼if (isForceResponseEncoding()) {response.setCharacterEncoding(encoding);}}// 如果 encoding 沒有配置,則使用默認(rèn)的編碼格式filterChain.doFilter(request, response);} }案例
無同名請求參數(shù)
-
在 test_param.html 頁面編寫超鏈接
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>測試請求參數(shù)</title> </head> <body><h1>測試請求參數(shù)</h1><!-- 通過控制器方法的形參獲取請求參數(shù) --><a th:href="@{/parameter(name='tom', age=18)}">通過控制器方法的形參獲取請求參數(shù)</a><br/> </body> </html> -
編寫對應(yīng)控制器方法
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 {/*** 通過控制器方法的形參獲取請求參數(shù)(無重名屬性寫法)* 如果沒有重名的請求參數(shù)傳過來,那么只需要將傳過來的請求參數(shù)名和控制器方法中的參數(shù)名保持一致即可*/@RequestMapping("/parameter")public String doParameter(String name, Integer age) {System.out.println(name + "--->" + age); // tom--->18return "success";} } -
啟動Tomcat查看效果
控制臺打印:admin--->12345--->籃球,足球
有同名請求參數(shù)
-
在 test_param.html 頁面編寫表單
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>測試請求參數(shù)</title> </head> <body><h1>測試請求參數(shù)</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> -
編寫對應(yīng)控制器方法
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 {/*** 通過控制器方法的形參獲取請求參數(shù)(無重名屬性寫法)* 如果有多個重名的請求參數(shù)傳過來(比如表單中的復(fù)選框),則可以使用下面的幾種方式接收:* 1、可以使用請求參數(shù)名與控制參數(shù)名相同的方式進(jìn)行接收(String hobby),多個值之間默認(rèn)會使用逗號分隔(a,b,c)* 2、可以使用一個數(shù)組進(jìn)行接收(String[] hobby)* > 大家可根據(jù)自己的需求進(jìn)行使用*/@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查看效果
效果和無同名參數(shù)是一樣的,都可以獲取到對應(yīng)的請求參數(shù)
@RequestParam 注解獲取請求參數(shù)
-
@RequestParam 是將請求參數(shù)和控制器方法的形參創(chuàng)建映射關(guān)系
-
@RequestParam 注解一共有三個屬性:
-
value:指定為形參賦值的請求參數(shù)的參數(shù)名
-
required:設(shè)置是否必須傳輸此請求參數(shù),默認(rèn)值為 true
若設(shè)置為true時,則當(dāng)前請求必須傳輸value所指定的請求參數(shù),若沒有傳輸該請求參數(shù),且沒有設(shè)置 defaultValue 屬性,則頁面報錯 400:Required String parameter 'xxx' is not present;若設(shè)置為 false,則當(dāng)前請求不是必須傳輸 value 所指定的請求參數(shù),若沒有傳輸,則注解所標(biāo)識的形參的值為 null
-
defaultValue:不管 required 屬性值為 true 或 false,當(dāng) value 所指定的請求參數(shù)沒有傳輸或傳輸?shù)闹禐?“”(空字符串)時,則使用默認(rèn)值為形參賦值
-
案例
-
在 test_param.html 頁面編寫表單
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>測試請求參數(shù)</title> </head> <body><h1>測試請求參數(shù)</h1><!-- 使用注解方式獲取請求參數(shù) --><form method="get" th:action="@{/parameter3}"><!-- 用戶名設(shè)置為 user_name,這樣后端的 username 形參就接收不到了這個時候就需要使用 @RequestParam 注解進(jìn)行獲取 -->用戶名:<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> -
編寫對應(yīng)控制器方法
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--->籃球,足球
雖然瀏覽器發(fā)送請求的時候帶了 user_name,但是控制器方法中并沒有可以接收這個值的參數(shù),所以最后得到的值就是 null
-
使用 @RequestParam 注解獲取請求參數(shù)
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 注解獲取請求參數(shù)* 參數(shù)說明:* name:請求參數(shù)名稱* value:請求參數(shù)名稱(這個參數(shù)用的比 name 要多,但是效果是一樣的)* required:默認(rèn)為true,表示是否必須傳輸 value或name 對應(yīng)的請求參數(shù)* (比如這里對應(yīng)的請求參數(shù)為 user_name,如果我們在請求映射的時候發(fā)現(xiàn)請求參數(shù)中并沒有 user_name 這個值,那么就會報 400)* defaultValue:默認(rèn)值,如果沒有傳輸 value或name 對應(yīng)的請求參數(shù),則會使用我們設(shè)置的默認(rèn)值* 如果傳輸了對應(yīng)的請求參數(shù),則使用傳輸過來的值* 該屬性會將 required 值設(shè)置為 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";} }大家可以結(jié)合注釋中的屬性說明,進(jìn)行設(shè)置,然后測試對應(yīng)的效果,我這里就不一 一展示了
-
再次測試
控制臺打印:admin--->123456--->籃球,足球(具體打印的數(shù)據(jù)就是這些,只是格式不同罷了,大家不要太較真),因為我們還設(shè)置了默認(rèn)值,所以如果在表單提交的時候 user_name 為空,那么最后打印的就是 haha--->123456--->籃球,足球,有興趣的話可以測試一下
@RequestHeader 注解
- @RequestHeader 是將請求頭信息和控制器方法的形參創(chuàng)建映射關(guān)系
- @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>測試請求參數(shù)</title> </head> <body><h1>測試請求參數(shù)</h1><!-- 使用 @RequestHeader 注解獲取請求頭信息 --><a th:href="@{/header}">測試@RequestHeader注解獲取請求頭信息</a><br/> </body> </html> -
編寫對應(yīng)控制器方法
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 獲取到所有的請求頭信息,也可以只獲取請求頭信息中某一個參數(shù)* > @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查看效果
- 瀏覽器就是頁面跳轉(zhuǎn)成功的效果
- 主要還是看控制臺打印,大家也可以直接把 Map 設(shè)置為返回值,然后把獲取的請求頭存進(jìn) Map 中然后進(jìn)行返回,這樣就可以看到在頁面中看到獲取到的請求頭數(shù)據(jù)了(也可以直接使用 F12 進(jìn)行查看)
@CookieValue
- @CookieValue 是將 cookie 數(shù)據(jù)和控制器方法的形參創(chuàng)建映射關(guān)系
- @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>測試請求參數(shù)</title> </head> <body><h1>測試請求參數(shù)</h1><!-- 使用 @CookieValue 注解獲取 Cookie 信息 --><a th:href="@{/cookie}">測試@CookieValue注解獲取請求頭信息</a><br/> </body> </html> -
編寫對應(yīng)控制器方法
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 中進(jìn)行查看*/@RequestMapping("/cookie")public String doCookie(@CookieValue("JSESSIONID") String jsessionid) {System.out.println("---->" + jsessionid);return "success";} } -
啟動Tomcat查看效果
- 主要看控制臺的打印效果,所以這里就不截圖了,大家可自行查看
通過 POJO 獲取請求參數(shù)
可以在控制器方法的形參位置設(shè)置一個實(shí)體類類型的形參,此時若瀏覽器傳輸?shù)恼埱髤?shù)的參數(shù)名和實(shí)體類中的屬性名一致,那么請求參數(shù)就會為此屬性賦值。
案例
-
編寫對應(yīng)實(shí)體類
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>測試請求參數(shù)</title> </head> <body><h1>測試請求參數(shù)</h1><!-- 通過 POJO 獲取請求參數(shù) --><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獲取參數(shù)"></form> </body> </html> -
編寫對應(yīng)控制器方法
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 獲取請求參數(shù)* 在需要傳輸多個請求參數(shù)的時候最好就是用這種方式* 如果全部寫在控制器方法的形參中會顯得非常冗余,而且也比較麻煩*/@RequestMapping("/doUser")public String doPojo(User user) {System.out.println(user);return "success";} } -
啟動Tomcat查看效果
此時在瀏覽器輸入完對于的表單數(shù)據(jù)后,控制器方法中就可以正常拿到對應(yīng)的參數(shù)值,并進(jìn)行打印(記得一定要配置好編碼格式!)
域?qū)ο蠊蚕頂?shù)據(jù)
-
為了整潔,創(chuàng)建一個新的工程來進(jìn)行演示,和之前一樣的東西: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 {/*** 跳轉(zhuǎn)至首頁*/@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 域?qū)ο蠊蚕頂?shù)據(jù)
-
在 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 域?qū)ο蠊蚕頂?shù)據(jù) --> <a th:href="@{/doServletAPI}">使用ServletAPI向request域?qū)ο蠊蚕頂?shù)據(jù)</a><br/></body> </html> -
編寫對應(yīng)控制器方法
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域?qū)ο蠊蚕頂?shù)據(jù)*/@RequestMapping("/doServletAPI")public String doRequest(HttpServletRequest request) {request.setAttribute("name", "我是張三!");return "success";} } -
創(chuàng)建 success.html 頁面,并獲取域?qū)ο?/strong>
<!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head><meta charset="UTF-8"><title>測試多種獲取域?qū)ο蟮姆绞?span id="ozvdkddzhkzd" class="token tag"></title> </head> <body><h1>測試多種獲取域?qū)ο蟮姆绞?span id="ozvdkddzhkzd" class="token tag"></h1><p th:text="${name}"></p></body> </html> -
啟動Tomcat查看效果
使用ModelAndView向request域?qū)ο蠊蚕頂?shù)據(jù)
-
在 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 域?qū)ο蠊蚕頂?shù)據(jù) --> <a th:href="@{/doModelAndView}">使用ModelAndView向request域?qū)ο蠊蚕頂?shù)據(jù)</a><br/> </body> </html> -
編寫對應(yīng)控制器方法
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 域?qū)ο蠊蚕頂?shù)據(jù)*/@RequestMapping("/doModelAndView")public ModelAndView doModelAndView() {ModelAndView modelAndView = new ModelAndView();// 處理模型數(shù)據(jù),即向請求域 request 共享數(shù)據(jù)modelAndView.addObject("modelAndView", "Hello, ModelAndView");// 設(shè)置視圖名稱(也就是頁面名稱)modelAndView.setViewName("success");return modelAndView;} } -
在 success.html 頁面獲取域?qū)ο?/strong>
<!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head><meta charset="UTF-8"><title>測試多種獲取域?qū)ο蟮姆绞?span id="ozvdkddzhkzd" class="token tag"></title> </head> <body><h1>測試多種獲取域?qū)ο蟮姆绞?span id="ozvdkddzhkzd" class="token tag"></h1> <!-- 使用 ModelAndView 方式共享的數(shù)據(jù) --> <p th:text="${modelAndView}"></p></body> </html> -
啟動Tomcat查看效果
使用 Model 向 request 域?qū)ο蠊蚕頂?shù)據(jù)
-
在 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 域?qū)ο蠊蚕頂?shù)據(jù) --> <a th:href="@{/doModel}">使用Model向request域?qū)ο蠊蚕頂?shù)據(jù)</a><br/></body> </html> -
編寫對應(yīng)控制器方法
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 域?qū)ο蠊蚕頂?shù)據(jù)*/@RequestMapping("/doModel")public String doModel(Model model) {model.addAttribute("model", "代碼人,代碼魂!");return "success";} } -
在 success.html 頁面獲取域?qū)ο?/strong>
<!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head><meta charset="UTF-8"><title>測試多種獲取域?qū)ο蟮姆绞?span id="ozvdkddzhkzd" class="token tag"></title> </head> <body><h1>測試多種獲取域?qū)ο蟮姆绞?span id="ozvdkddzhkzd" class="token tag"></h1><!-- 使用 Model 方式共享的數(shù)據(jù) --> <p th:text="${model}"></p></body> </html> -
啟動Tomcat查看效果
使用 Map 向 request 域?qū)ο蠊蚕頂?shù)據(jù)
-
在 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 域?qū)ο蠊蚕頂?shù)據(jù) --> <a th:href="@{/doMap}">使用Map向request域?qū)ο蠊蚕頂?shù)據(jù)</a><br/></body> </html> -
編寫對應(yīng)控制器方法
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 域?qū)ο蠊蚕頂?shù)據(jù)*/@RequestMapping("/doMap")public String doMap(Map<String, Object> map) {// map 中添加的每一個數(shù)據(jù)就是一個共享數(shù)據(jù)map.put("map", "代碼小白!");return "success";} } -
在 success.html 頁面獲取域?qū)ο?/strong>
<!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head><meta charset="UTF-8"><title>測試多種獲取域?qū)ο蟮姆绞?span id="ozvdkddzhkzd" class="token tag"></title> </head> <body><h1>測試多種獲取域?qū)ο蟮姆绞?span id="ozvdkddzhkzd" class="token tag"></h1><!-- 使用 ModelMap 方式共享的數(shù)據(jù) --> <p th:text="${modelMap}"></p> </body> </html> -
啟動Tomcat查看效果
使用 ModelMap 向 request 域?qū)ο蠊蚕頂?shù)據(jù)
-
在 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 域?qū)ο蠊蚕頂?shù)據(jù) --> <a th:href="@{/doModelMap}">使用ModelMap向request域?qū)ο蠊蚕頂?shù)據(jù)</a><br/></body> </html> -
編寫對應(yīng)控制器方法
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 域?qū)ο蠊蚕頂?shù)據(jù)*/@RequestMapping("/doModelMap")public String doModelMap(ModelMap modelMap) {modelMap.addAttribute("modelMap", "2022必沒bug!!!");return "success";} } -
在 success.html 頁面獲取域?qū)ο?/strong>
<!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head><meta charset="UTF-8"><title>測試多種獲取域?qū)ο蟮姆绞?span id="ozvdkddzhkzd" class="token tag"></title> </head> <body><h1>測試多種獲取域?qū)ο蟮姆绞?span id="ozvdkddzhkzd" class="token tag"></h1> <!-- 使用 ModelMap 方式共享的數(shù)據(jù) --> <p th:text="${modelMap}"></p> </body> </html> -
啟動Tomcat查看效果
Model、ModelMap、Map的關(guān)系
一共有五種共享方式:
- 第一種:使用 ServletAPI(不建議使用)
- 第二種:使用 ModelAndView
- 第三種:使用 Model
- 第四種:使用 Map
- 第五種:使用 ModelMap
Model、Map、ModelMap 的關(guān)系:
BindingAwareModelMap 以及父級的部分源碼: public class BindingAwareModelMap extends ExtendedModelMap {} public class ExtendedModelMap extends ModelMap implements Model {} public class ModelMap extends LinkedHashMap<String, Object> {}這三個方式都是通過 BindingAwareModelMap 類進(jìn)行實(shí)例化的: 因為 BindingAwareModelMap 繼承了 ExtendedModelMap,而 ExtendedModelMap 繼承了 ModelMap,所以BindingAwareModelMap 可以對 ModelMap 進(jìn)行實(shí)例化 因為 BindingAwareModelMap 繼承了 ExtendedModelMap,而 ExtendedModelMap 實(shí)現(xiàn)了 Model,所以BindingAwareModelMap 可以對 Model 進(jìn)行實(shí)例化 因為 BindingAwareModelMap 繼承了 ExtendedModelMap,而 ExtendedModelMap 繼承了 ModelMap,而 ModelMap 又繼承了 LinkedHashMap,所以可以對 Map 進(jìn)行實(shí)例化使用 ServletAPI 向 session 域共享數(shù)據(jù)
-
在 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 域共享數(shù)據(jù) --> <a th:href="@{/doSession}">使用ServletAPI向session域共享數(shù)據(jù)</a><br/></body> </html> -
編寫對應(yīng)控制器方法
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 域共享數(shù)據(jù)*/@RequestMapping("/doSession")public String doSession(HttpSession session) {session.setAttribute("servletApi", "這是session數(shù)據(jù)~");return "success";} } -
在 success.html 頁面獲取 session 域?qū)ο?/strong>
<!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head><meta charset="UTF-8"><title>測試多種獲取域?qū)ο蟮姆绞?span id="ozvdkddzhkzd" class="token tag"></title> </head> <body><h1>測試多種獲取域?qū)ο蟮姆绞?span id="ozvdkddzhkzd" class="token tag"></h1> <!-- 使用 ServletAPI 向 Session域共享的數(shù)據(jù) --> <p th:text="${session.servletApi}"></p></body> </html>注意:在頁面獲取 session 數(shù)據(jù)的時候需要使用 “session.屬性” 才可以獲取到對應(yīng)的值
-
啟動Tomcat查看效果
使用ServletAPI向application域共享數(shù)據(jù)
-
在 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 域共享數(shù)據(jù) --> <a th:href="@{/doApplication}">使用ServletAPI向application域共享數(shù)據(jù)</a><br/></body> </html> -
編寫對應(yīng)控制器方法
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 域共享數(shù)據(jù)*/@RequestMapping("/doApplication")public String doApplication(HttpSession session) {ServletContext application = session.getServletContext();application.setAttribute("applicationScope", "這是application的數(shù)據(jù)哦!");return "success";} } -
在 success.html 頁面獲取 application 域?qū)ο?/strong>
<!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head><meta charset="UTF-8"><title>測試多種獲取域?qū)ο蟮姆绞?span id="ozvdkddzhkzd" class="token tag"></title> </head> <body><h1>測試多種獲取域?qū)ο蟮姆绞?span id="ozvdkddzhkzd" class="token tag"></h1> <!-- 使用 ServletAPI 向 application域共享的數(shù)據(jù) --> <p th:text="${application.applicationScope}"></p> </body> </html>調(diào)用的方式和 session 的差不多,也是需要使用“”對應(yīng)的域?qū)ο?對應(yīng)的屬性” 才能獲取到對應(yīng)的值
-
啟動Tomcat查看效果
四大作用域說明
application 作用域
-
如果把變量放到 application 里,就說明它的作用域是 application。
-
有效范圍:application 的有效范圍是整個應(yīng)用;整個應(yīng)用是指從應(yīng)用啟動,到應(yīng)用結(jié)束。我們沒有說 “從服務(wù)器啟動,到服務(wù)器關(guān)閉”,是因為一個服務(wù)器可能部署多個應(yīng)用,當(dāng)然你關(guān)閉了服務(wù)器,就會把上面所有的應(yīng)用都關(guān)閉了。
application 作用域里的變量,它們的存活時間是最長的,如果不手動刪除,它們就可以一直使用。
-
Object getAttribute(String name) //從application中獲取信息;
-
void setAttribute(String name,Object value) //向application作用域中設(shè)置信息。
session 作用域
- 如果把變量放到 session 里,就說明它的作用域是session(session 存放在服務(wù)器端的內(nèi)存中)。
- 有效范圍:它的有效范圍是當(dāng)前會話;所謂當(dāng)前會話,就是指從用戶打開瀏覽器開始,到用戶關(guān)閉瀏覽器這中間的過程。
- Object HttpSession.getAttribute(String name) //從session中獲取信息。
- void HttpSession.setAttribute(String name,Object value)//向session中保存信息。
- HttpSessionHttpServletRequest.getSessio() //獲取當(dāng)前請求所在的session的對象。
了解
-
session 從瀏覽器發(fā)出第一個 HTTP 請求即可認(rèn)為會話開始。但結(jié)束就不好判斷了,因為瀏覽器關(guān)閉時并不會通知服務(wù)器,所以只能通過如下這種方法判斷:
如果一定的時間內(nèi)客戶端沒有反應(yīng),則認(rèn)為會話結(jié)束。
-
Tomcat 的默認(rèn)值為 120 分鐘,但這個值也可以通過 HttpSession的setMaxInactiveInterval() 方法來設(shè)置:
void setMaxInactiveInterval(int interval)
-
如果想主動讓會話結(jié)束,例如用戶單擊 “注銷” 按鈕的時候,可以使用 HttpSession 的 invalidate() 方法,用于強(qiáng)制結(jié)束當(dāng)前 session
刪除 session 的三種方式
- Session 超時:超時指的是連續(xù)一定時間服務(wù)器沒有收到該 Session 所對應(yīng)客戶端的請求,并且這個時間超過了服務(wù)器設(shè)置的 Session 超時的最大時間。
- 程序調(diào)用 HttpSession.invalidate()
- 服務(wù)器關(guān)閉或服務(wù)停止
注意
request 作用域
-
request 里的變量可以跨越 forward 前后的兩頁,但是只要刷新頁面,它們就重新計算了。
-
請求轉(zhuǎn)發(fā):servlet. getRequestDispatcher("new.jsp").forward(req,resp);
注意:
page 作用域
- page 對象的作用范圍僅限于用戶請求的當(dāng)前頁面
- request 和 page 的生命周期都是短暫的,它們之間的區(qū)別:一個 request 可以包含多個 page 頁(include,forward 及 filter)。
更多可看這位大佬寫的博客:https://m.php.cn/article/418934.html
SpringMVC 的視圖
- SpringMVC 中的視圖是 View 接口,視圖的作用:渲染數(shù)據(jù),將模型 Model 中的數(shù)據(jù)展示給用戶 SpringMVC 視圖的種類很多,默認(rèn)有轉(zhuǎn)發(fā)視圖和重定向視圖;
- 當(dāng)工程引入 jstl 的依賴,轉(zhuǎn)發(fā)視圖會自動轉(zhuǎn)換為 JstlView
- 若使用的視圖技術(shù)為 Thymeleaf,在 SpringMVC 的配置文件中配置了 Thymeleaf 的視圖解析器,由此視圖解析器解析之后所得到的是 ThymeleafView
ThymeleafView
當(dāng)控制器方法中所設(shè)置的視圖名稱沒有任何前綴時,此時的視圖名稱會被 SpringMVC 配置文件中所配置的視圖解析器解析,視圖名稱拼接視圖前綴和視圖后綴所得到的最終路徑,會通過轉(zhuǎn)發(fā)的方式實(shí)現(xiàn)跳轉(zhuǎn)。
案例
-
創(chuàng)建 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> -
編寫對應(yīng)控制器方法
package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;@Controller public class ViewController {/*** 跳轉(zhuǎn)至視圖測試頁面*/@RequestMapping("/doView")public String doView() {return "view";}/*** 默認(rèn)(無前綴)* ThymeleafView 視圖對象*/@RequestMapping("/doThymeleafView")public String doThymeleafView() {return "success";} } -
啟動Tomcat查看效果
- 正常效果就是可以正常訪問到 view 頁面和 success 頁面,這里就不截圖了(localhost:8080/springmvc/doView)
- 實(shí)現(xiàn)原理可看下面的原理分析
原理分析
部分源碼:
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封裝的模型數(shù)據(jù)和視圖信息processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}// 處理ModelAndView封裝的模型數(shù)據(jù)和視圖信息private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,@Nullable Exception exception) throws Exception {if (mv != null && !mv.wasCleared()) {// 如果視圖不為空,則將該視圖進(jìn)行渲染render(mv, request, response);if (errorView) {WebUtils.clearErrorRequestAttributes(request);}}}// 渲染視圖protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {// 本地化(就是本地的環(huán)境,由兩個部分組成,一個是語言碼,一個是國家碼,比如 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) {/* 根據(jù)視圖名稱和ModelAndView中封裝的模型數(shù)據(jù)獲取到視圖對象因為我們沒有在控制器方法返回的時候設(shè)置前綴,所以這里創(chuàng)建的是一個ThymeleafView(視圖對象)> 可簡單理解為:當(dāng)控制器方法中所設(shè)置的視圖名稱沒有任何前綴時,得到的就是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() + "'");}}} }注意:以上只是部分源碼解析,如果想要看到更加詳細(xì)的,可以自行去源碼中探索!
轉(zhuǎn)發(fā)視圖
-
SpringMVC 中默認(rèn)的轉(zhuǎn)發(fā)視圖是 InternalResourceView
-
SpringMVC 中創(chuàng)建轉(zhuǎn)發(fā)視圖的情況:
當(dāng)控制器方法中所設(shè)置的視圖名稱以 “forward:” 為前綴時,就會創(chuàng)建 InternalResourceView 視圖,此時的視圖名稱不會被 SpringMVC 配置文件中所配置的視圖解析器解析,而是會將前綴 “forward:” 去掉,剩余部分作為最終路徑通過轉(zhuǎn)發(fā)的方式實(shí)現(xiàn)跳轉(zhuǎn)。
例如"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> -
編寫對應(yīng)控制器方法
package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;@Controller public class ViewController {/*** 跳轉(zhuǎn)至視圖測試頁面*/@RequestMapping("/doView")public String doView() {return "view";}/*** 默認(rèn)(無前綴)* ThymeleafView 視圖對象*/@RequestMapping("/doThymeleafView")public String doThymeleafView() {return "success";}/*** 轉(zhuǎn)發(fā)視圖(前綴為:“forward:”)* InternalResourceView 視圖對象*/@RequestMapping("/doForward")public String doInternalResourceView() {/*1、使用 forward 為前綴時不能直接訪問具體的頁面(會報404),因為頁面必須通過服務(wù)器進(jìn)行訪問>錯誤寫法:return "forward:success";2、如果想要通過 forward 訪問到具體頁面,可以轉(zhuǎn)發(fā)到一個跳轉(zhuǎn)到某個頁面的控制器方法(控制器方法設(shè)置的請求路徑)中比如:forward:/doThymeleafView3、這里最終頁面顯示的地址是 /doForward,而不是 /doThymeleafView*/return "forward:/doThymeleafView";} } -
啟動Tomcat查看效果
- 正常效果就是可以正常訪問到 view 頁面和 success 頁面,這里就不截圖了
原理分析
- 關(guān)鍵的一些源碼還是剛才的那些,所以這里就不做記錄了
重定向視圖
-
SpringMVC 中默認(rèn)的重定向視圖是 RedirectView
-
當(dāng)控制器方法中所設(shè)置的視圖名稱以 “redirect:” 為前綴時,創(chuàng)建 RedirectView視圖,此時的視圖名稱不會被 SpringMVC 配置文件中所配置的視圖解析器解析,而是會將前綴 “redirect:” 去掉,剩余部分作為最終路徑通過重定向的方式實(shí)現(xiàn)跳轉(zhuǎn)。
例如"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> -
編寫對應(yīng)控制器方法
package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;@Controller public class ViewController {/*** 跳轉(zhuǎn)至視圖測試頁面*/@RequestMapping("/doView")public String doView() {return "view";}/*** 默認(rèn)(無前綴)* ThymeleafView 視圖對象*/@RequestMapping("/doThymeleafView")public String doThymeleafView() {return "success";}/*** 重定向視圖(前綴為:“redirect:”)* RedirectView 視圖對象*/@RequestMapping("/doRedirect")public String doRedirectView() {/*1、使用 redirect 為前綴時不能直接訪問具體的頁面(會報404)>錯誤寫法:return "redirect:success";2、如果想要通過 redirect 訪問到具體頁面,可以轉(zhuǎn)發(fā)到一個跳轉(zhuǎn)到某個頁面的控制器方法(控制器方法設(shè)置的請求路徑)中比如:redirect:/doThymeleafView3、這里最終頁面顯示的地址是 /doThymeleafView,而不是 /doRedirect*/return "redirect:/doThymeleafView";} } -
啟動Tomcat查看效果
- 正常效果就是可以正常訪問到 view 頁面和 success 頁面,這里就不截圖了
原理分析
- 關(guān)鍵的一些源碼還是剛才的哪些,所以這里就不做記錄了
轉(zhuǎn)發(fā)與重定向(理解)
轉(zhuǎn)發(fā)與重定向的作用:在 Servlet 中實(shí)現(xiàn)頁面的跳轉(zhuǎn)
轉(zhuǎn)發(fā)
-
概念:由服務(wù)器進(jìn)行的頁面跳轉(zhuǎn)就被稱為 “轉(zhuǎn)發(fā)”
-
特點(diǎn):
- 地址欄不發(fā)生變化,顯示的是上一個頁面的地址
- 請求次數(shù):只有一次請求(就是瀏覽器向服務(wù)器發(fā)送的那一次請求)
- 請求域數(shù)據(jù)不會丟失
- 根目錄:http://localhost:8080/項目地址/,包含了項目的訪問地址
-
原生 Servlet 實(shí)現(xiàn)轉(zhuǎn)發(fā)使用 request.getRequestDispatcher("/地址").forward(request, response);
-
SpringMVC 使用轉(zhuǎn)發(fā)在返回的地址前使用 redirect: 當(dāng)做前綴(底層會進(jìn)行解析,最后得到一個 InternalResourceView 視圖對象)
重定向
- 概念:由服務(wù)器進(jìn)行的頁面跳轉(zhuǎn)就被稱為 “重定向”
- 特點(diǎn):
- 地址欄顯示的是新的地址
- 請求次數(shù):兩次
- 請求域中的數(shù)據(jù)會丟失,因為是兩次次請求
- 根目錄:http://localhost:8080/,沒有項目的訪問地址
SpringMVC 視圖控制器(view-controller)
當(dāng)控制器方法中,僅僅用來實(shí)現(xiàn)頁面跳轉(zhuǎn),即只需要設(shè)置視圖名稱時,可以將處理器方法使用 view-controller標(biāo)簽進(jìn)行表示。
注意:
1、如果不單單是跳轉(zhuǎn)頁面,而是進(jìn)行了一定的操作,那么就不要使用 view-controller,因為 view-controller 無法實(shí)現(xiàn)對應(yīng)操作!
2、在配置文件中配置view-controller之后,會導(dǎo)致 controller 控制器中的所有請求映射失效
-
注釋掉 index 的請求映射
package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;@Controller public class TestController {/*** 跳轉(zhuǎn)至首頁*/ // @RequestMapping("/") // public String doIndex() { // return "index"; // }} -
在 spring-mvc.xml 配置文件中使用 view-controller 標(biāo)簽進(jìn)行處理
<?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"><!-- 優(yōu)先級 --><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:設(shè)置處理的請求地址,該路徑是和 @RequestMapping 注解中的地址是一樣的簡單理解:就是把 controller 中用來跳轉(zhuǎn)頁面的控制器方法寫在了配置文件中view-controller:設(shè)置請求地址所對應(yīng)的視圖名稱注意:1、如果不單單是跳轉(zhuǎn)頁面,而是進(jìn)行了一定的操作,那么就不要寫在配置文件中,因為配置文件無法實(shí)現(xiàn)對應(yīng)操作!2、在配置文件中配置view-controller之后,會導(dǎo)致 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>為了更好的看懂,我這里還配置了一個跳轉(zhuǎn)到 view.html 頁面的 view-controller,記得要把對應(yīng)控制器中的控制器方法注釋掉! 不注釋掉的話可能會出現(xiàn)一些不必要的問題。
-
啟動Tomcat測試效果
-
訪問方式:localhost:8080/springmvc/
-
訪問方式:localhost:8080/springmvc/doView
-
可以看到,我們在配置文件中配置的路徑是可以正常訪問到對應(yīng)的頁面的,但是此時會有一個小問題,就是點(diǎn)擊頁面的超鏈接之后會報 404,這是因為 view-controller 標(biāo)簽會導(dǎo)致所有控制器中的請求映射失效。
-
-
解決請求映射失效問題(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"><!-- 優(yōu)先級 --><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:設(shè)置處理的請求地址,該路徑是和 @RequestMapping 注解中的地址是一樣的view-controller:設(shè)置請求地址所對應(yīng)的視圖名稱--><!-- 訪問方式: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 的注解驅(qū)動 --><mvc:annotation-driven /> </beans> -
再次測試
此時點(diǎn)擊超鏈接就可以正常進(jìn)行映射了
SpringMVC 視圖解析器(InternalResourceViewResolver)
我們上面使用的視圖解析器都是解析 html 頁面的(ThymeleafViewResolver),但如果視圖使用的是 JSP 頁面,那么就需要使用 InternalResourceViewResolver 視圖解析器
-
創(chuàng)建一個新的項目,然后把 web.xml、pom 依賴復(fù)制到這個新項目中
-
在 resource 目錄下創(chuàng)建并編寫 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 目錄下創(chuàng)建 index.jsp
-
說明:
Tomcat 的 web.xml 文件中配置了默認(rèn)歡迎頁(index.html,index.htm,index.jsp);但是在 Tomcat 中,每一個 webapp 目錄下的子目錄都被認(rèn)為是一個 JSP 站點(diǎn),所以只能訪問到 index.jsp 歡迎頁
如果在 webapp 目錄下同時創(chuàng)建了 index.html 和 index.jsp,那么訪問的時候就會報 404,如果只有 index.html,那么啟動后也是會報404,因為訪問不到默認(rèn)頁
-
-
在 WEB-INF/templates 目錄下創(chuàng)建 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> -
編寫對應(yīng)的控制器方法,實(shí)現(xiàn)頁面跳轉(zhuǎn)
package com.laoyang.mvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;/*** @ClassName JspController* @Description: JSP 跳轉(zhuǎn)* @Author Laoyang* @Date 2022/1/10 17:12*/ @Controller public class JspController {@RequestMapping("/doSuccess")public String doSuccess() {// 這里返回的 jsp 頁面會被 spring-mvc.xml 配置文件中的視圖解析器進(jìn)行解析return "success";} }
總結(jié)
以上是生活随笔為你收集整理的SpringMVC视图及如何在域对象中共享数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【互联网营销基础知识】新媒体工具亲民替代
- 下一篇: 重学JavaWeb —— JSP,简单全