SpringMVC框架學習筆記(四):模型數據 以及 視圖和視圖解析器

1?模型數據處理-數據放入 request

說明:開發中, 控制器/處理器中獲取的數據如何放入 request 域,然后在前端(VUE/JSP/...)取出顯 示

1.1?方式 1: 通過 HttpServletRequest 放入 request

(1)前端發送請求

<h1>添加主人信息</h1>
<form action="vote/vote05" method="post">主人號:<input type="text" name="id"><br>主人名:<input type="text" name="name"><br>寵物號:<input type="text" name="pet.id"><br>寵物名:<input type="text" name="pet.name"><br><input type="submit" value="添加主人和寵物">
</form>

(2)后端接收請求

springmvc會自動把獲取的model模型,放入到request域中

/*** 1. 將提交的數據封裝到java對象->springmvc 會自動的將其放入到request域* 2. 這樣我們就可以在跳轉到的頁面取出數據.*/
@RequestMapping(value = "/vote05")
public String test05(Master master, HttpServletRequest request) {//1. springmvc會自動把獲取的model模型,放入到request域中,名字就是master//2. 也可以手動將master放入到requestrequest.setAttribute("address", "beijing");//3. 如果我們希望修改master的屬性值master.setName("nono");//4. 分析一下springmvc默認存放對象到request域中,屬性名是//   request域 ("master", master) 屬性名是類名/類型名 首字母小寫//返回到一個結果return "vote_ok";
}

(3)跳轉頁面

<h1>獲取的的數據顯示頁面</h1>
<hr>
取出 request域的數據-通過 el表達式來獲取
<br>
address: ${requestScope.address}<br>
主人名字= ${requestScope.master.name}
主人id= ${requestScope.master.id}
寵物名字= ${requestScope.master.pet.name}

(4)頁面顯示結果

1.2?方式 2: 通過請求的方法參數 Map<String,Object> 放入 request

(1)前端發送請求

<h1>添加主人信息[測試 Map ]</h1>
<form action="vote/vote06" method="post">主人號:<input type="text" name="id"><br>主人名:<input type="text" name="name"><br>寵物號:<input type="text" name="pet.id"><br>寵物名:<input type="text" name="pet.name"><br><input type="submit" value="添加主人和寵物">
</form>

(2)后端接收請求

/*** 通過Map<String,Object> 設置數據到request域*/
@RequestMapping(value = "/vote06")
public String test06(Master master, Map<String, Object> map) {//1. 需求是通過map對象,添加屬性到request中//2. 原理分析:springmvc會遍歷map,然后將map的k-v, 存放到request域map.put("address", "beijing...");//返回到一個結果return "vote_ok";
}

(3)跳轉頁面同方式1

(4)頁面顯示結果

1.3?方式 3: 通過返回 ModelAndView 對象 實現 request 域數據

(1)前端發送請求

<h1>添加主人信息[測試ModelAndView]</h1>
<form action="vote/vote07" method="post">主人號:<input type="text" name="id"><br>主人名:<input type="text" name="name"><br>寵物號:<input type="text" name="pet.id"><br>寵物名:<input type="text" name="pet.name"><br><input type="submit" value="添加主人和寵物">
</form>

(2)后端接收請求

說明:

  • 從本質看,請求響應的方法 return "xx", 是返回了一個字符串,其實本質是返回了一個 ModelAndView 對象,只是默認被封裝起來的.
  • ModelAndView 即可以包含 model 數據,也可以包含視圖信息
  • ModelAndView 對象的 addObject 方法可以添加 key-val 數據,默認在 request 域中
  • ModelAndView 對象 setView 方法可以指定視圖名稱
/*** 通過返回ModelAndView對象,將數據放入到request域*/
@RequestMapping(value = "/vote07")
public ModelAndView test07(Master master) {System.out.println("----test07----");ModelAndView modelAndView = new ModelAndView();//放入屬性到modelAndView對象modelAndView.addObject("address", "shanghai");//可以把從數據庫得到的數據->對象,放入modelAndView//這里指定跳轉的視圖名稱modelAndView.setViewName("vote_ok");//返回結果return modelAndView;
}

(3)跳轉頁面同方式1

(4)頁面顯示結果

2?模型數據處理-數據放入 session

說明:開發中, 控制器/處理器中獲取的數據如何放入 session 域,然后在前端(VUE/JSP/...)取出顯 示

應用實例:

(1)前端發送請求

<h1>添加主人信息[測試session]</h1>
<form action="vote/vote08" method="post">主人號:<input type="text" name="id"><br>主人名:<input type="text" name="name"><br>寵物號:<input type="text" name="pet.id"><br>寵物名:<input type="text" name="pet.name"><br><input type="submit" value="添加主人和寵物">
</form>

(2)后端接收請求

/*** 將數據設置到session域中*/
@RequestMapping(value = "/vote08")
public String test08(Master master, HttpSession httpSession) {System.out.println("----test08----");//master對象是默認放在request域//這里將master對象放入到session域httpSession.setAttribute("master", master);httpSession.setAttribute("address", "guangzhou");return "vote_ok";//請求轉發
}

(3)跳轉頁面

取出 session域的數據 <br>
address: ${sessionScope.address}<br>
主人名字= ${sessionScope.master.name}
主人信息= ${sessionScope.master}

(4)頁面顯示結果

3 @ModelAttribute 實現 prepare 方法

說明:開發中,有時需要使用某個前置方法(比如 prepareXxx(), 方法名由程序員定)給目標方法準 備一個模型對象

@ModelAttribute 注解可以實現 這樣的需求,在某個方法上,增加了@ModelAttribute 注解后 那么在調用該 Handler 的任何一個方法時,都會先調用這個方法

案例:

/*** 1. 當Handler的方法被標識 @ModelAttribute,就視為一個前置方法* 2. 當調用該Handler的其它的方法時,都會先執行該前置方法* 3. 類似Spring中AOP的前置通知[底層是AOP機制]* 4. prepareModel前置方法,會切入到其它方法前執行*/
@ModelAttribute
public void prepareModel(){System.out.println("prepareModel()-----完成準備工作-----");
}

使用場景舉例:

修改用戶信息(就是經典的使用這種機制的應用),流程如下:

1. 在修改前,在前置方法中從數據庫查出這個用戶

2. 在修改方法(目標方法)中,可以使用前置方法從數據庫查詢的用戶

3. 如果表單中對用戶的某個屬性修改了,則以新的數據為準,如果沒有修改,則以數據庫 的信息為準,比如,用戶的某個屬性不能修改,就保持原來的值?

4?視圖和視圖解析器

4.1?基本介紹

(1)在 springMVC 中的目標方法最終返回都是一個視圖(有各種視圖).

(2)返回的視圖都會由一個視圖解析器來處理 (視圖解析器有很多種)

4.2 自定義視圖

4.2.1?為什么需要自定義視圖

(1)在默認情況下,我們都是返回默認的視圖, 然后這個返回的視圖交由 SpringMVC 的 InternalResourceViewResolver 視圖處理器來處理的

<!--下面配置springMVC的視圖解析器,如果我們的controller return 的是 login_ok
那么要跳轉的頁面頁面就是 /WEB-INF/pages/login_ok-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--配置屬性suffix(后綴) 和 prefix(前綴)--><property name="prefix" value="/WEB-INF/pages/"/><property name="suffix" value=".jsp"/>
</bean>

(2)在實際開發中,我們有時需要自定義視圖,這樣可以滿足更多更復雜的需求.

4.2.2 自定義視圖實例-代碼實現

(1)配置 applicationContext-mvc, 增加自定義視圖解析器

<!--
1. 配置自定義視圖解析器BeanNameViewResolver
2. BeanNameViewResolver可以去解析我們自定義的視圖
3. 配置 屬性 order, 表示視圖解析器執行的順序, 值越小, 優先級越高
4. 屬性 order 的默認值是最低優先級 ,值為 Integer.MAX_VALUEint LOWEST_PRECEDENCE = 2147483647
-->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"><property name="order" value="99"/>
</bean>

(2)創建 MyView.java - 自定義視圖類

package com.web.viewresolver;import org.springframework.stereotype.Component;
import org.springframework.web.servlet.view.AbstractView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;/*** 1. MyView繼承了AbstractView, 就可以作為一個視圖使用* 2. @Component(value = "myView"),該視圖會注入到容器中, 名字/id是 myView*/
@Component(value = "myView")
public class MyView extends AbstractView {@Overrideprotected void renderMergedOutputModel(Map<String, Object> model,HttpServletRequest request,HttpServletResponse response) throws Exception {//完成視圖渲染//并且可以確定我們要跳轉的頁面 [請求轉發]System.out.println("進入到自己的視圖..");//1. 下面就是進行請求轉發到 /WEB-INF/pages/my_view.jsp//2. /WEB-INF/pages/my_view.jsp 會被springmvc解析成 /springmvc/WEB-INF/pages/my_view.jsprequest.getRequestDispatcher("/WEB-INF/pages/my_view.jsp").forward(request, response);}
}

(3)創建 GoodsHandler.java

@RequestMapping("/goods")
@Controller
public class GoodsHandler {@RequestMapping(value = "/buy")public String buy() {System.out.println("------buy()-----");// 這里返回自定義視圖類在容器中的名字/idreturn "myView";}
}

(4)創建 web\view.jsp 和 /WEB-INF/pages/my_view.jsp?

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>自定義視圖測試</title>
</head>
<body>
<h1>自定義視圖測試</h1>
<a href="goods/buy">點擊到自定義視圖-</a><br/>
<a href="goods/order">測試在目標方法中指定請求轉發或者重定向的頁面-</a><br/>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>my_view頁面</title>
</head>
<h1>進入到my_view頁面</h1>
<p>是從自定義視圖來的..</p>
<body></body>
</html>

?(5)效果如下

初始頁面:

跳轉頁面:

4.2.3?自定義視圖工作流程小結

自定義視圖-小結

  • 自定義視圖: 創建一個 View 的 bean, 該 bean 需要繼承自 AbstractView, 并實現 renderMergedOutputModel 方法.
  • 需要把自定義 View 加入到 IOC 容器中
  • 自定義視圖的視圖處理器,使用 BeanNameViewResolver, 這個視圖處理器也需要配置 到 ioc 容器
  • BeanNameViewResolver 的調用優先級需要設置一下,設置 order 比 Integer.MAX_VAL 小的值. 以確保其在 InternalResourceViewResolver 之前被調用

自定義視圖-工作流程

  • SpringMVC 調用目標方法, 返回自定義 View 在 IOC 容器中的 id
  • SpringMVC 調用 BeanNameViewResolver 解析視圖: 從 IOC 容器中獲取 返回 id 值對 應的 bean, 即自定義的 View 的對象
  • SpringMVC 調用自定義視圖的 renderMergedOutputModel 方法渲染視圖
  • 說明: 如果在 SpringMVC 調用目標方法, 返回自定義 View 在 IOC 容器中的 id, 不存在, 則仍然按照默認的視圖處理器機制處理。但是如果先按照默認視圖解析器進行解析,就是解析出來的頁面不存在,也不會進入到自定義解析器,而會直接報錯

4.3?目標方法直接指定轉發或重定向

4.3.1 說明

(1)默認返回的方式是請求轉發,然后用視圖處理器進行處理,比如在目標方法中這樣寫:

@RequestMapping(value = "/login")
public String login(){System.out.println("login ok....");return "login_ok";
}

(2)也可以在目標方法直接指定重定向或轉發的 url 地址

(3)如果指定重定向,不能定向到 /WEB-INF 目錄中,因為這個目錄是tomcat的一個類路徑

4.3.2 應用實例

(1)修改 GoodsHandler.java, 增加方法 order()?

/*** 演示直接指定要請求轉發的或者是重定向的頁面*/
@RequestMapping(value = "/order")
public String order() {System.out.println("=======order()=====");//請求轉發到 /WEB-INF/pages/my_view.jsp//forward 關鍵字表示請求轉發//請求轉發可以到/WEB-INF/ 目錄下,也可以轉發到這個目錄外面的頁面//下面的 /WEB-INF/pages/my_view.jsp 會被解析成 /springmvc/WEB-INF/pages/my_view.jsp//return "forward:/WEB-INF/pages/my_view.jsp"; // 等價于 return "my_view.jsp"//請求轉發到/WEB-INF/目錄外面的頁面//return "forward:/aaa/bbb/ok.jsp";//直接指定要重定向的頁面//1. 對于重定向來說,可以重定向到web目錄,不能重定向到 /WEB-INF/ 目錄下//2. redirect 關鍵字,表示進行重定向//3. /login.jsp 在服務器解析 /springmvc/login.jspreturn "redirect:/login.jsp";// /WEB-INF/pages/my_view.jsp 被解析 /springmvc/WEB-INF/pages/my_view.jsp 該路徑是訪問不到的//return "redirect:/WEB-INF/pages/my_view.jsp";//這樣寫會報錯
}

?(2)前端發出請求

<a href="goods/order">測試在目標方法中指定請求轉發或者重定向的頁面-</a><br/>

?(3)跳轉頁面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>登錄成功</title>
</head>
<body>
<h1>恭喜 登錄成功</h1>
</body>
</html>

(4)跳轉成功

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/19489.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/19489.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/19489.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用dockerfile快速構建一個帶ssh的docker鏡像

不多說先給代碼 FROM ubuntu:22.04 # 基礎鏡像 可替換為其他鏡像 USER root RUN echo root:root |chpasswd RUN apt-get update -y \&& apt-get install -y git wget curl RUN apt-get install -y openssh-server vim && apt clean \&& rm -rf /tmp/…

在SpringBoot項目中實現切面執行鏈功能

1.定義切面執行鏈頂級接口 AspectHandler /*** 切面執行鏈**/ public interface AspectHandler {/*** 設置排除項* param excludes*/default void setExcludes(List<String> excludes) {}/*** 獲取排除項* return*/default List<String> getExcludes() {return ne…

事務與并發控制

事務&#xff08;Transaction0&#xff09;&#xff1a;要么全做&#xff0c;要么全不做&#xff1b; 事務ACID&#xff1a;原子性Atomicity&#xff1b;一致性Consistency&#xff1b;隔離性Isolation&#xff1b;持久性Durability&#xff1b; 并發操作問題&#xff1a; 1.…

基于RNN和Transformer的詞級語言建模 代碼分析 _generate_square_subsequent_mask

基于RNN和Transformer的詞級語言建模 代碼分析 _generate_square_subsequent_mask flyfish Word-level Language Modeling using RNN and Transformer word_language_model PyTorch 提供的 word_language_model 示例展示了如何使用循環神經網絡RNN(GRU或LSTM)和 Transforme…

汽車IVI中控開發入門及進階(二十二):video decoder視頻解碼芯片

前言: 視頻解碼器在許多汽車、專業和消費視頻應用中仍有需求。Analog Devices是模擬視頻產品領域的行業領導者,提供一系列視頻解碼器,可將標準(SD,standard definition)和高清(HD,High definition)分辨率的模擬視頻高質量轉換為MIPI或TTL格式的數字視頻數據。典型的應…

【AI大模型】如何讓大模型變得更聰明?基于時代背景的思考

【AI大模型】如何讓大模型變得更聰明 前言 在以前&#xff0c;AI和大模型實際上界限較為清晰。但是隨著人工智能技術的不斷發展&#xff0c;基于大規模預訓練模型的應用在基于AI人工智能的技術支持和幫助上&#xff0c;多個領域展現出了前所未有的能力。無論是自然語言處理、…

算法刷題筆記 差分矩陣(C++實現)

文章目錄 題目前言題目描述解題思路和代碼實現 題目前言 這道題是一道差分算法的拓展題型&#xff0c;是算法刷題筆記到目前為止我認為最困難的題目之一。因此&#xff0c;這篇題解博客的過程記錄也最為詳細&#xff0c;希望能夠為你帶來幫助。 題目描述 輸入一個n行m列的整…

JavaScript的垃圾回收機制

No.內容鏈接1Openlayers 【入門教程】 - 【源代碼示例300】 2Leaflet 【入門教程】 - 【源代碼圖文示例 150】 3Cesium 【入門教程】 - 【源代碼圖文示例200】 4MapboxGL【入門教程】 - 【源代碼圖文示例150】 5前端就業寶典 【面試題詳細答案 1000】 文章目錄 一、垃圾…

匹配字符串

自學python如何成為大佬(目錄):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 Python提供了re模塊&#xff0c;用于實現正則表達式的操作。在實現時&#xff0c;可以使用re模塊提供的方法&#xff08;如search()、match()、finda…

深入理解Redis:多種操作方式詳解

Redis&#xff08;Remote Dictionary Server&#xff09;是一款高性能的開源鍵值存儲系統&#xff0c;廣泛應用于緩存、會話管理、實時分析等領域。它支持多種數據結構&#xff0c;如字符串、哈希、列表、集合和有序集合等&#xff0c;提供了豐富的操作命令。本篇博客將詳細介紹…

信息系統項目管理師0603:項目整合管理 — 考點總結(可直接理解記憶)

點擊查看專欄目錄 文章目錄 項目整合管理 — 考點總結(可直接理解記憶) 輸入、輸出、工具和技術 歷年考題直接考輸入,輸出、工具和技術的有17年11月第34、35,19年5月第34、35,20年11月27、28,21年5月第26,28,21年11月第28,22年5月第25,22年11月第22考題 項目章程是正…

CasaOS玩客云安裝全平臺高速下載器Gopeed并實現遠程訪問

&#x1f49d;&#x1f49d;&#x1f49d;歡迎來到我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;希望您在這里可以感受到一份輕松愉快的氛圍&#xff0c;不僅可以獲得有趣的內容和知識&#xff0c;也可以暢所欲言、分享您的想法和見解。 推薦:kwan 的首頁,持續學…

BufferQueue 的工作原理

bufferQueue 是 Android 圖形棧中的一個核心組件,它在生產者和消費者之間傳遞緩沖區(buffer)。它通常用于圖形緩沖區管理,特別是在 SurfaceFlinger 和其他圖形相關的組件中。理解 BufferQueue 的工作原理對開發高性能圖形應用和解決圖形渲染問題非常有幫助。 BufferQueue …

基于Python的酒店客房入侵檢測系統的設計與實現

基于Python的酒店客房入侵檢測系統的設計與實現 開發語言:Python 數據庫&#xff1a;MySQL所用到的知識&#xff1a;Django框架工具&#xff1a;pycharm、Navicat、Maven 系統功能實現 酒店客房入侵管理界面 結合上文的結構搭建和用戶需求&#xff0c;酒店客房入侵檢測系統的…

【Unity Shader入門精要 第12章】屏幕后處理效果(一)

1. 原理和過程 屏幕后處理是綁定攝像機的&#xff0c;通過抓取當前攝像機渲染的圖像作為 SrcTextrue&#xff0c;然后按需依次調用處理接口&#xff0c;對 SrcTexture 進行處理&#xff0c;最后將處理完成的 DstTexture 顯示到屏幕上&#xff0c;整個過程的調度通過 C# 腳本完…

使用 C++ 在當前進程中獲取指定模塊的基址

C 實現 , 獲取指定模塊在該進程中的基址 1、流程: 獲取進程的所有模塊信息–>遍歷模塊列表 2、實現&#xff1a; // 我自己定義的 typedef struct moudle_date_ {HANDLE mhandle; // 句柄char mname[64]; // 名稱char* date; // 數據DWORD mdword; // 基址…

【機器學習】Adaboost: 強化弱學習器的自適應提升方法

&#x1f308;個人主頁: 鑫寶Code &#x1f525;熱門專欄: 閑話雜談&#xff5c; 炫酷HTML | JavaScript基礎 ?&#x1f4ab;個人格言: "如無必要&#xff0c;勿增實體" 文章目錄 Adaboost: 強化弱學習器的自適應提升方法引言Adaboost基礎概念弱學習器與強學習…

存儲器容量小才使用SRAM芯片,容量較大時使用DRAM芯片。為什么?

在計算機系統中&#xff0c;存儲器容量的選擇涉及到多種因素&#xff0c;包括成本、速度和復雜性。SRAM&#xff08;靜態隨機存取存儲器&#xff09;和DRAM&#xff08;動態隨機存取存儲器&#xff09;是兩種常見的內存類型&#xff0c;它們在設計和應用上有顯著的不同。以下是…

【藍橋杯嵌入式】 第六屆國賽

目錄 題目 配置 注意事項 代碼 - 默寫大師 EEPROM讀寫函數 LED驅動函數 ADC采集 上電初始化 LCD 按鍵 PWM互補輸出 全部代碼 hardware.c hardware.h control.c control.h main.c 題目 配置 注意事項 復制LCD的工程&#xff0c;先配置資源 --- 勾選完選項一…

CCIG 2024:合合信息文檔解析技術突破與應用前景

目錄 背景當前大模型訓練和應用面臨的問題訓練Token耗盡訓練語料質量要求高LLM文檔問答應用中文檔解析不精準 合合信息的文檔解析技術1. 具備多文檔元素識別能力2. 具備版面分析能力3. 高性能的文檔解析4. 高精準、高效率的文檔解析文檔多板式部分示例 文檔解析典型技術難點元素…