Spring MVC 中請求處理流程及核心組件解析

在 Spring MVC 中,請求從客戶端發送到服務器后,需要經過一系列組件的處理才能最終到達具體的 Controller 方法。這個過程涉及多個核心組件和復雜的映射機制,下面詳細解析其工作流程:

1. 核心組件與請求流程

Spring MVC 的請求處理流程主要涉及以下核心組件:

DispatcherServlet:前端控制器,接收所有 HTTP 請求,是整個請求處理的入口。

HandlerMapping:請求映射處理器,負責將請求 URL 映射到對應的 Handler(即 Controller 方法)。

HandlerAdapter:處理器適配器,將不同類型的 Handler 統一為可執行的接口。

Controller:具體的業務控制器,處理請求并返回 ModelAndView。

ViewResolver:視圖解析器,將邏輯視圖名解析為具體的 View 對象。

View:視圖對象,負責將模型數據渲染到客戶端。

請求處理流程

客戶端請求 → DispatcherServlet → HandlerMapping → HandlerAdapter →Controller → ModelAndView → ViewResolver → View → 響應客戶端

2. HandlerMapping 的請求映射機制

HandlerMapping 是實現 URL 到 Controller 方法映射的核心組件,Spring MVC 提供了多種實現:

RequestMappingHandlerMapping:處理 @RequestMapping 注解的映射(最常用)。

BeanNameUrlHandlerMapping:根據 Bean 名稱映射請求(如 /hellohelloController Bean)。

SimpleUrlHandlerMapping:通過配置文件手動指定 URL 與 Handler 的映射關系。

基于注解的映射流程

當使用 @RequestMapping 或其派生注解(如 @GetMapping)時:

啟動時掃描:Spring MVC 在啟動時會掃描所有帶有 @Controller@RestController 注解的 Bean。

解析方法映射:提取這些 Bean 中所有標注了 @RequestMapping 的方法,構建映射關系。

生成 HandlerMethod 對象:將每個映射方法封裝為 HandlerMethod 對象,包含控制器實例、方法反射信息和請求匹配條件(如 URL、請求方法、請求參數等)。

注冊到映射器:將 HandlerMethod 對象注冊到 RequestMappingHandlerMapping 的內部映射表中。

3. DispatcherServlet 的請求分發

當接收到請求時,DispatcherServlet 會按以下步驟處理:

獲取 HandlerExecutionChain

HandlerExecutionChain handler = getHandler(request);

DispatcherServlet 調用 HandlerMappinggetHandler(request) 方法,根據請求 URL 查找匹配的 Handler。

HandlerMapping 返回一個 HandlerExecutionChain 對象,包含 Handler(即 Controller 方法)和相關的攔截器(Interceptor)。

獲取 HandlerAdapter

HandlerAdapter ha = getHandlerAdapter(handler.getHandler());

DispatcherServlet 根據 Handler 的類型,從已注冊的 HandlerAdapter 中選擇合適的適配器。

例如,RequestMappingHandlerAdapter 用于處理基于注解的 Controller 方法。

執行 Handler

ModelAndView mv = ha.handle(request, response, handler.getHandler());

HandlerAdapter 調用 Controller 方法,并傳遞請求參數,獲取返回的 ModelAndView

4. 參數解析與返回值處理

參數解析

HandlerAdapter 通過 HandlerMethodArgumentResolver 解析請求參數:

內置解析器:Spring MVC 提供多種解析器,例如:

RequestParamMethodArgumentResolver:解析 @RequestParam 注解的參數。

PathVariableMethodArgumentResolver:解析路徑變量(如 /users/{id})。

RequestBodyArgumentResolver:解析請求體(如 JSON、XML),需配合 @RequestBody 注解。

自定義解析器:可實現 HandlerMethodArgumentResolver 接口自定義參數解析邏輯。

返回值處理

HandlerAdapter 通過 HandlerMethodReturnValueHandler 處理返回值:

內置處理器:例如:

ViewNameMethodReturnValueHandler:處理返回視圖名的方法。

ModelAndViewMethodReturnValueHandler:處理返回 ModelAndView 的方法。

ResponseBodyEmitterReturnValueHandler:處理異步返回值(如 ResponseEntity)。

@ResponseBody 注解:若方法標注了 @ResponseBody,則通過 HttpMessageConverter 將返回值序列化為響應體(如 JSON)。

5. 示例:從請求到 Controller 的完整流程

假設存在以下 Controller:

@RestController@RequestMapping("/api/users")public class UserController {@Autowiredprivate UserService userService;@GetMapping("/{id}")public UserDTO getUser(@PathVariable Long id) {return userService.getUserById(id);}}

請求流程

客戶端發送請求 GET /api/users/123

DispatcherServlet 接收請求,調用 RequestMappingHandlerMapping

HandlerMapping 根據 URL /api/users/123 和請求方法 GET,匹配到 UserController.getUser() 方法。

DispatcherServlet 獲取 HandlerAdapter(即 RequestMappingHandlerAdapter)。

HandlerAdapter 解析路徑變量 id=123,并調用 UserController.getUser(123)

Controller 方法返回 UserDTO 對象。

由于 @RestController 隱含 @ResponseBody,HandlerAdapter 通過 HttpMessageConverterUserDTO 序列化為 JSON。

DispatcherServlet 將 JSON 響應返回給客戶端。

6. 攔截器與異常處理

攔截器(Interceptor)

在請求到達 Controller 前后,可通過攔截器執行額外邏輯:

實現 HandlerInterceptor 接口

public class LoggingInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) {// 請求處理前執行(如日志記錄、權限校驗)return true; // 繼續執行后續流程}@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) {// 請求處理后、視圖渲染前執行}@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) {// 完成請求處理(如資源清理)}}

注冊攔截器

@Configurationpublic class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoggingInterceptor()).addPathPatterns("/api/**"); // 攔截所有 API 請求}}
異常處理

通過 @ControllerAdvice@ExceptionHandler 統一處理異常:

@ControllerAdvicepublic class GlobalExceptionHandler {@ExceptionHandler(NotFoundException.class)public ResponseEntity<String> handleNotFoundException(NotFoundException ex) {return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());}}

總結

Spring MVC 通過 HandlerMapping 實現 URL 到 Controller 方法的映射,通過 HandlerAdapter 統一調用不同類型的 Handler,并借助 參數解析器返回值處理器 完成請求參數和響應數據的轉換。整個過程由 DispatcherServlet 協調,配合攔截器和異常處理機制,形成了一個完整的請求處理體系。理解這些機制,有助于更高效地開發和調試 Spring MVC 應用。

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

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

相關文章

RISC-V 開發板 MUSE Pi Pro V2D圖像加速器測試,踩坑介紹

視頻講解&#xff1a; RISC-V 開發板 MUSE Pi Pro V2D圖像加速器測試&#xff0c;踩坑介紹 今天測試下V2D&#xff0c;這是K1特有的硬件級別的2D圖像加速器&#xff0c;參考如下文檔&#xff0c;但文檔中描述的部分有不少問題&#xff0c;后面會講下 https://bianbu-linux.spa…

hbase shell的常用命令

一、hbase shell的基礎命令 # 版本號查看 [rootTest-Hadoop-NN-01 hbase]$ ./bin/hbase version HBase 2.4.0 Source code repository git://apurtell-ltm.internal.salesforce.com/Users/apurtell/src/hbase revision282ab70012ae843af54a6779543ff20acbcbb629# 客戶端登錄 […

深入解析Python中的Vector2d類:從基礎實現到特殊方法的應用

引言 在Python面向對象編程中&#xff0c;特殊方法&#xff08;或稱魔術方法&#xff09;是實現對象豐富行為的關鍵。本文將以Vector2d類為例&#xff0c;詳細講解如何通過特殊方法為自定義類添加多種表示形式和操作能力。 Vector2d類的基本行為 Vector2d類是一個二維向量類…

Zookeeper入門(三)

Zookeeper Java 客戶端 項目構建 ookeeper 官方的客戶端沒有和服務端代碼分離&#xff0c;他們為同一個jar 文件&#xff0c;所以我們直接引入 zookeeper的maven即可&#xff0c; 這里版本請保持與服務端版本一致&#xff0c;不然會有很多兼容性的問題 1 <dependency>…

Redis的主從架構

主從模式 全量同步 首先主從同步過程第一步 會先比較replication id 判斷是否是第一次同步假設為第一次同步 那么就會 啟動bgsave異步生成RDB 同時fork子進程記錄生成期間的新數據發送RDB給從節點 清空本地數據寫入RDB 增量同步 對比ReplicationID不同因此選擇增量同步在Rep…

新電腦軟件配置二:安裝python,git, pycharm

安裝python 地址 https://www.python.org/downloads/ 不是很懂為什么這么多版本 安裝windows64位的 這里我是憑自己感覺裝的了 然后cmd輸入命令沒有生效&#xff0c;先重啟下&#xff1f; 重啟之后再次驗證 環境是成功的 之前是輸入的python -version 命令輸入錯誤 安裝pyc…

docker 學習記錄

docker pull nginx docker 將本地nginx快照保存到當前文件夾下 docker save -o nginx.tar nginx:latestdocker 將本地nginx 加載 docker load -i nginx.tar docker運行nginx在80端口 docker run --name dnginx -p 80:80 -d nginxredis啟動 docker run --name mr -p 6379:6379 -…

什么是私有IP地址?如何判斷是不是私有ip地址

在互聯網的世界中&#xff0c;IP地址是設備之間通信的基礎標識。無論是瀏覽網頁、發送郵件還是在線游戲&#xff0c;IP地址都扮演著至關重要的角色。然而&#xff0c;并非所有的IP地址都是公開的&#xff0c;有些IP地址被保留用于內部網絡&#xff0c;這就是我們所說的私有IP地…

功能安全管理

一、功能安全整體管理 1、功能安全文化&#xff0c;良好的功能安全文化包括&#xff1a; 1&#xff09; 在公司層面&#xff0c;有清晰的組織架構支撐功能安全開展 2&#xff09; 確保有足夠的資源投入到功能安全開發中 3&#xff09; 有完整的功能安全培訓 4&#xff09; 流程…

異常日志規范

目錄 一、錯誤碼 二、異常處理 三、日志規約 一、錯誤碼 強制&#xff1a; 1、錯誤碼的制訂原則&#xff1a;快速溯源、溝通標準化。 1&#xff09;錯誤碼必須能夠快速知曉錯誤來源&#xff0c;可快速判斷是誰的問題。 2&#xff09;錯誤碼必須能夠清晰地比對&#xff08;…

SOLID 面對象設計的五大基本原則

SOLID 原則的價值 原則核心價值解決的問題SRP職責分離&#xff0c;提高內聚性代碼臃腫、牽一發而動全身OCP通過擴展而非修改實現變化頻繁修改現有代碼導致的風險LSP確保子類行為的一致性繼承濫用導致的系統不穩定ISP定制化接口&#xff0c;避免依賴冗余接口過大導致的實現負擔…

Python 裝飾器詳解

裝飾器是 Python 中一種強大的語法特性&#xff0c;它允許在不修改原函數代碼的情況下動態地擴展函數的功能。裝飾器本質上是一個高階函數&#xff0c;它接受一個函數作為參數并返回一個新的函數。 基本裝飾器 1. 簡單裝飾器示例 def my_decorator(func):def wrapper():prin…

無損耗協議:PROFINET和EtherNet IP網關的高效安裝指南

作為風力發電機組監控系統的重要組成部分&#xff0c;PROFINET和EtherNet/IP協議轉換網關倍訊BX-606-EIP的安裝至關重要。作為安裝工,我們要確保網關安裝的高效順利,保證風力發電機組的穩定運行。 首先,我們需要仔細檢查網關的硬件接口,確保所有連接線纜與設備端口相匹配。網關…

Axure元件動作四:設置選中

親愛的小伙伴,在您瀏覽之前,煩請關注一下,在此深表感謝!如有幫助請訂閱專欄! Axure產品經理精品視頻課已登錄CSDN可點擊學習https://edu.csdn.net/course/detail/40420 課程主題:設置選中 主要內容:選中效果全面解析 應用場景:元件、元件組合需要被選中場景 案例展…

大模型為什么學新忘舊(大模型為什么會有災難性遺忘)?

字數&#xff1a;2500字 一、前言&#xff1a;當學霸變成“金魚” 假設你班上有個學霸&#xff0c;數學考滿分&#xff0c;英語拿第一&#xff0c;物理稱霸全校。某天&#xff0c;他突然宣布&#xff1a;“我要全面發展&#xff01;從今天起學打籃球&#xff01;” 一周后&am…

通過SMTP協議實現Linux郵件發送配置指南

一、環境準備與基礎配置 1. SMTP服務開通&#xff08;以qq郵箱為例&#xff09; 登錄qq郵箱網頁端&#xff0c;進入「設置」-「POP3/SMTP/IMAP」 開啟「SMTP服務」并獲取16位授權碼&#xff08;替代郵箱密碼使用&#xff09; 記錄關鍵參數&#xff1a; SMTP服務器地址&#…

react中安裝依賴時的問題 【集合】

目錄 依賴升級/更新 1、 npm install --save-dev 與 npm install 的區別 1. ?安裝位置&#xff08;依賴類型&#xff09;? 2. ?package.json 中的區別? 3. ?示例 4. ?何時使用哪種方式? 2、npm install 和 yarn add 有什么不一樣嗎 ?命令語法?&#xff1a; …

Coze 實戰教程 | 10 分鐘打造你的AI 助手

> 文章中的 xxx 自行替換&#xff0c;文章被屏蔽了。 &#x1f4f1; 想讓你的xxx具備 AI 對話能力&#xff1f;本篇將手把手教你&#xff0c;如何用 Coze 平臺快速構建一個能與用戶自然交流、自動回復提問的 xxx助手&#xff0c;零代碼、超高效&#xff01; &#x1f4cc;…

【Spring Cloud Gateway】Nacos整合遇坑記:503 Service Unavailable

一、場景重現 最近在公司進行微服務架構升級&#xff0c;將原有的 Spring Cloud Hoxton 版本升級到最新的 2021.x 版本&#xff0c;同時使用 Nacos 作為服務注冊中心和配置中心。在完成基礎框架搭建后&#xff0c;我使用 Spring Cloud Gateway 作為API 網關&#xff0c;通過 N…

寶塔面板屏蔽垃圾搜索引擎蜘蛛和掃描工具的辦法

首先進入寶塔面板&#xff0c;文件管理進入/www/server/nginx/conf目錄&#xff0c;新建空白文件kill_bot.conf。然后將以下代碼保存到當前文件中。 #禁止垃圾搜索引擎蜘蛛抓取if ($http_user_agent ~* "CheckMarkNetwork|Synapse|Nimbostratus-Bot|Dark|scraper|LMAO|Ha…