解讀Spring MVC的工作流程
Spring MVC 的工作流程是基于模型-視圖-控制器(MVC)設(shè)計模式的一個典型實現(xiàn),以下是其主要工作流程步驟:
Spring MVC 的工作流程
客戶端請求發(fā)送到前端控制器(DispatcherServlet):
- 用戶通過瀏覽器發(fā)送請求,該請求首先到達 Spring MVC 的前端控制器
DispatcherServlet
。 - 這個類是整個流程的核心,它負責(zé)協(xié)調(diào)其他組件的執(zhí)行。
前端控制器轉(zhuǎn)發(fā)請求給處理器映射器(Handler Mapping):
DispatcherServlet
接收到請求后,依據(jù)請求的 URL 查找相應(yīng)的處理器(Controller
)來處理請求。- 這個映射由
Handler Mapping
完成,它根據(jù)配置查找具體的處理器。
處理器映射器找到相應(yīng)的控制器(Controller):
Handler Mapping
根據(jù)請求的路徑,確定使用哪個Controller
來處理請求。- 找到之后,它返回
Controller
的信息給DispatcherServlet
。
前端控制器調(diào)用目標(biāo)處理器(Controller):
DispatcherServlet
根據(jù)Handler Mapping
提供的信息,調(diào)用具體的Controller
處理請求。- 控制器中的業(yè)務(wù)邏輯會處理客戶端的數(shù)據(jù),并返回一個
ModelAndView
對象,包含了模型數(shù)據(jù)和視圖名稱。
控制器返回模型數(shù)據(jù)和視圖名稱:
Controller
將處理后的模型數(shù)據(jù)和視圖名稱返回給DispatcherServlet
。
前端控制器請求視圖解析器(View Resolver):
DispatcherServlet
將視圖名稱交給視圖解析器View Resolver
- 由它負責(zé)將視圖名稱解析為具體的視圖(比如 JSP、Thymeleaf 等)
視圖解析器生成視圖:
- 視圖解析器會根據(jù)配置找到相應(yīng)的物理視圖文件
- 并返回給
DispatcherServlet
前端控制器將模型數(shù)據(jù)傳遞給視圖:
DispatcherServlet
將控制器返回的模型數(shù)據(jù)傳遞給解析出來的視圖- 通常這些數(shù)據(jù)會通過
Model
或ModelAndView
對象傳遞
視圖渲染:
- 視圖結(jié)合模型數(shù)據(jù)進行渲染
- 生成最終的 HTML 頁面
前端控制器響應(yīng)客戶端:
- 渲染后的視圖由
DispatcherServlet
返回給客戶端(瀏覽器) - 最終用戶看到的是處理后的頁面內(nèi)容
例子
假設(shè)我們有一個簡單的 Web 應(yīng)用程序,用于顯示用戶的個人信息。當(dāng)用戶訪問 /user/1
這個 URL 時,應(yīng)用程序會展示 ID 為 1 的用戶信息。
詳細步驟
用戶發(fā)送請求到服務(wù)器: 用戶在瀏覽器中輸入 URL /user/1
,比如 http://localhost:8080/user/1
,這個請求被發(fā)送到服務(wù)器。
前端控制器(DispatcherServlet)接收請求: Spring MVC 的核心組件 DispatcherServlet
會攔截所有進入的 HTTP 請求。它相當(dāng)于請求的入口點,負責(zé)將請求分發(fā)到適當(dāng)?shù)奶幚砥鳎–ontroller)。
- 例子中的請求路徑
/user/1
被DispatcherServlet
攔截,準備分配給相應(yīng)的處理器。
通過處理器映射器(Handler Mapping)查找控制器: DispatcherServlet
使用處理器映射器(HandlerMapping
)查找合適的控制器來處理 /user/1
請求。這個映射過程通常是根據(jù) URL 路徑來匹配的。
- 例如,
@RequestMapping("/user/{id}")
注解可以告訴 Spring 這個方法負責(zé)處理/user/{id}
的請求。 - 在我們的例子中,處理器映射器會找到
UserController
,該控制器負責(zé)處理所有與用戶相關(guān)的請求。
控制器(Controller)處理請求: 找到合適的控制器后,DispatcherServlet
將請求轉(zhuǎn)發(fā)給控制器??刂破靼藨?yīng)用程序的業(yè)務(wù)邏輯,負責(zé)處理用戶請求和返回數(shù)據(jù)。
- 在這個例子中,
UserController
的方法會接受用戶的 ID(比如1
),然后從數(shù)據(jù)庫或內(nèi)存中獲取 ID 為 1 的用戶信息。
@Controller public class UserController { @RequestMapping("/user/{id}") public ModelAndView getUser(@PathVariable("id") int userId) { // 模擬從數(shù)據(jù)庫獲取用戶數(shù)據(jù) User user = userService.getUserById(userId); ModelAndView mav = new ModelAndView("userView"); mav.addObject("user", user); return mav; } }
在這個例子中:
getUser
方法會從userService
獲取用戶數(shù)據(jù),并將該數(shù)據(jù)存儲在ModelAndView
對象中,返回給DispatcherServlet
。"userView"
是視圖的名稱,Spring MVC 會根據(jù)這個名稱來找到合適的視圖模板(比如 JSP 頁面、Thymeleaf 頁面等)。mav.addObject("user", user)
將用戶信息存儲在模型中,供視圖使用。
返回模型和視圖給 DispatcherServlet: 控制器方法返回一個 ModelAndView
對象,包含了模型數(shù)據(jù)(用戶信息)和視圖名稱(userView
)。DispatcherServlet
接收這個返回對象。
通過視圖解析器(View Resolver)查找視圖: DispatcherServlet
會將視圖名稱(如 "userView"
)交給視圖解析器(ViewResolver
),由它根據(jù)配置找到物理視圖文件。
視圖解析器生成視圖: 視圖解析器會找到 userView.jsp
并返回給 DispatcherServlet
。此時,視圖還沒有渲染出用戶數(shù)據(jù),只是找到了物理文件。
前端控制器將模型數(shù)據(jù)傳遞給視圖: DispatcherServlet
將控制器返回的用戶數(shù)據(jù)(模型)傳遞給 userView.jsp
視圖。視圖文件會使用這些數(shù)據(jù)生成動態(tài)的 HTML 頁面。
視圖渲染: 視圖(userView.jsp
)結(jié)合模型數(shù)據(jù)進行渲染。比如 JSP 文件中可能會使用表達式 ${user.name}
來顯示用戶的姓名。
返回響應(yīng)到客戶端: 渲染后的 HTML 頁面被返回給客戶端(用戶的瀏覽器)。用戶最終看到的是包含用戶信息的完整頁面。
注:
- 在使用 Spring Boot 進行前后端分離開發(fā)時,后端只負責(zé)提供數(shù)據(jù)接口(通常以 RESTful API 的形式),前端負責(zé)渲染頁面和處理用戶交互。
- 這種架構(gòu)在 Spring Boot 中表現(xiàn)為 RESTful API,而不再像傳統(tǒng) Spring MVC 那樣返回視圖。
- 與傳統(tǒng) MVC 不同,
Controller
使用@RestController
,直接返回 Java 對象,而不返回視圖。 - Spring Boot 會自動將返回的對象序列化為 JSON 或 XML。
@RestController public class UserController { @GetMapping("/user/{id}") public User getUser(@PathVariable("id") int id) { // 從服務(wù)層獲取用戶信息 return userService.getUserById(id); // 返回的是 User 對象,而不是視圖名稱 } }
傳統(tǒng) Spring MVC 返回視圖:
- 返回的是視圖文件(如 JSP 頁面)通過服務(wù)端渲染動態(tài) HTML。
- 控制器返回
ModelAndView
對象,包含視圖名稱和模型數(shù)據(jù)。 - 使用 JSP、Thymeleaf 等視圖引擎渲染視圖。
Spring Boot RESTful API:
- 返回的是 JSON 或 XML 格式的數(shù)據(jù),由前端或客戶端負責(zé)渲染。
- 使用
@RestController
,控制器直接返回對象,Spring Boot 自動將其轉(zhuǎn)換為 JSON。
總結(jié)
Spring MVC 的整個流程可以簡單總結(jié)為以下幾個步驟:
- 用戶發(fā)送請求到
DispatcherServlet
。 DispatcherServlet
使用HandlerMapping
查找對應(yīng)的控制器。- 控制器處理請求,生成
ModelAndView
。 DispatcherServlet
使用ViewResolver
解析視圖名稱。- 將模型數(shù)據(jù)傳遞給視圖進行渲染。
- 將渲染的視圖返回給用戶。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實現(xiàn)指定線程執(zhí)行順序的三種方式示例
這篇文章主要介紹了Java實現(xiàn)指定線程執(zhí)行順序的三種方式,包括通過共享對象鎖加上可見變量,通過主線程Join()以及通過線程執(zhí)行時Join()等三種實現(xiàn)方法,需要的朋友可以參考下2019-01-01基于Jenkins自動打包并部署docker環(huán)境的操作過程
這篇文章主要介紹了基于Jenkins自動打包并部署docker環(huán)境,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08Spring Boot 在啟動時進行配置文件加解密的方法詳解
這篇文章主要介紹了Spring Boot 在啟動時進行配置文件加解密的方法,本文通過實例給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06java+selenium 網(wǎng)易云音樂刷累計聽歌數(shù)的方法
這篇文章主要介紹了java+selenium 網(wǎng)易云音樂刷累計聽歌數(shù)的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06