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

