SpringMVC的核心架構與請求處理流程

Spring MVC 核心架構


核心組件

組件作用類比
DispatcherServlet前端控制器,統一接收請求并協調各組件處理一個餐廳的前臺
HandlerMapping根據請求URL映射到對應的處理器(Controller)路由表
HandlerAdapter執行處理器方法,處理參數綁定、方法調用等適配器(兼容不同處理器)
ViewResolver將邏輯視圖名解析為物理視圖(如JSP、Thymeleaf)地圖導航
View渲染模型數據生成最終響應(HTML/JSON等)廚師(加工數據)
HandlerExceptionResolver統一處理控制器拋出的異常故障應急小組

分層架構

客戶端 => DispatcherServlet => HandlerMapping

=>?Controller => ModelAndView => View => 響應

相當于

客戶端 => 前端控制器 => 處理器映射器 => 處理器 =>模型與視圖容器 => 響應器 =>響應

請求處理的流程

  1. 請求到達:客戶端發送http請求到前端控制器DispatcherServelt
  2. 查找處理器:前端控制器DispatcherServlet調用HandlerMapping確定目標控制器Controller
  3. 獲取適配器:通過處理器適配器HandlerAdapter執行控制器方法
  4. 攔截器預處理:執行攔截器鏈的preHandle()
  5. 參數綁定:適配器解析請求參數(路徑變量、表單數據等),傳遞給控制器方法
  6. 執行控制器:調用控制器Controller方法執行業務邏輯
  7. 返回模型與視圖:控制器Controller返回ModelAndView(或String視圖名、@ResponseBody等)
  8. 攔截器后處理:執行攔截器鏈后的postHandle()
  9. 視圖解析:視圖解析器ViewResolver將邏輯視圖名轉換為具體View對象
  10. 視圖渲染:響應器View渲染模型數據產生響應內容(HTML/JSON)
  11. 攔截器完成:執行攔截器鏈的afterCompletion()

關鍵環節:HTTP請求 → Java對象

當請求到達控制器方法前,Spring MVC會自動提取請求中的各種數據

@RequestParam:獲取URL查詢字符串參數

// 請求:/search?keyword=spring
@GetMapping("/search")
public String search(@RequestParam("keyword") String keyword) {// keyword = "spring"
}

@PathVariable:獲取URL路徑中的變量

// 請求:/users/123/profile
@GetMapping("/users/{userId}/profile")
public String profile(@PathVariable("userId") Long id) {// id = 123
}

@RequestBody:將JSON/XML請求體轉換為Java對象

// 請求體:{"name":"John","age":30}
@PostMapping("/users")
public User createUser(@RequestBody User user) {// user.getName() = "John"// user.getAge() = 30
}

表單綁定:自動將表單字段映射到對象屬性

// 表單字段:username=admin&password=123
@PostMapping("/login")
public String login(UserForm form) {// form.getUsername() = "admin"
}

配置視圖解析器的流程

(假如控制器返回一個字符串“success”)

控制器返回字符串?=> return ‘success’=> 視圖解析器=> 檢查配置

=> 前綴+字符串success+后綴=> 合成地址/WEB-INF/views/success.jsp=> 范文實際視圖文件

應用配置的前綴和后綴

resolver.setPrefix("/WEB-INF/views/"); // 視圖文件目錄
resolver.setSuffix(".jsp");            // 文件擴展名

配置文件示例:

@Configuration
public class WebConfig {@Beanpublic ViewResolver viewResolver() {InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setPrefix("/WEB-INF/views/"); // 視圖存放目錄resolver.setSuffix(".jsp");            // 文件擴展名return resolver;}
}

異常的分層處理

方法級處理(優先級最高)

@Controller
public class UserController {@ExceptionHandler(UserNotFoundException.class)public ResponseEntity<String> handleUserNotFound() {return ResponseEntity.status(404).body("用戶不存在");}
}

控制器級處理

@Controller
@ExceptionHandler({IllegalArgumentException.class, DataAccessException.class})
public ResponseEntity<String> handleControllerExceptions() {// 處理本控制器所有指定異常
}

全局處理(最常用)

@ControllerAdvice // 作用于所有控制器
public class GlobalExceptionHandler {// 處理特定異常@ExceptionHandler(ResourceNotFoundException.class)public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) {ErrorResponse error = new ErrorResponse("NOT_FOUND",ex.getMessage(),System.currentTimeMillis());return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);}// 兜底處理所有未捕獲異常@ExceptionHandler(Exception.class)public ResponseEntity<ErrorResponse> handleAllExceptions(Exception ex) {// 返回通用錯誤響應}
}

關于用戶訪問個人資料頁面的示例

請求GET /users/123/profile

參數綁定:提取路徑變量?userId=123

控制器方法處理:

@GetMapping("/users/{userId}/profile")
public String userProfile(@PathVariable Long userId, Model model) {User user = userService.findById(userId); // 可能拋出異常model.addAttribute("user", user);return "user/profile"; // 邏輯視圖名
}

處理異常:若用戶不存在,拋出UserNotFoundException

視圖解析:將"user/profile"轉換為/WEB-INF/views/user/profile.jsp

渲染頁面并返回響應

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

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

相關文章

css 不錯的按鈕動畫

效果圖wxml <view class"{{status?active:}}"><view class"up-top btn"><text>向上</text></view><view class"up-left btn"><text>向左</text></view><view class"up-center b…

若依框架RuoYi-Vue-Plus-5.X的啟動,本地安裝docker,再部署 Redis、PG數據庫(智慧水務)SmartWaterServer

一、部署redis數據庫拉取鏡像 docker pull redis啟動Redis容器docker run -d --name redis-server -p 6379:6379 -v redis-data:/data redis redis-server --requirepass 123redis版本二、部署PostgreSQL 數據庫拉取鏡像docker pull postgres:15 創建數據存儲目錄、建議將數據掛…

Idea 清除無用的引用類

在IntelliJ IDEA中&#xff0c;你可以通過以下方式將選中的代碼設置為大寫&#xff1a;1. 使用快捷鍵(推薦)Windows/Linux&#xff1a;Ctrl Shift UMac&#xff1a;Cmd Shift U操作步驟&#xff1a;選中文本按下快捷鍵&#xff0c;即可在大小寫之間切換。2. 通過菜單操作選…

同個主機拉取不同權限倉庫的方法

背景&#xff1a;因為某些神奇的原因&#xff0c;無法同時授權倉庫權限給自己。 1.本地電腦只有權限訪問web倉庫地址&#xff0c;無權限訪問backend倉庫&#xff1b; 2.堡壘機服務器只有權限訪問backend倉庫&#xff0c;無權限訪問web倉庫地址。 web倉庫地址 &#xff1a;codeu…

快速搭建Node.js服務指南

Node.js是構建高效、可擴展網絡應用的理想選擇。以下是幾種快速搭建Node.js服務的方法。 方法一&#xff1a;使用Express&#xff08;最流行框架&#xff09; 1. 初始化項目 mkdir my-node-service cd my-node-service npm init -y2. 安裝Express npm install express3. 基礎服…

通義千問Qwen3-30B-A3B-Thinking-2507技術解析:推理模型的工程實踐突破

Qwen3-30B-A3B模型架構圖2025年7月30日&#xff0c;阿里云通義千問團隊發布了Qwen3-30B-A3B-Thinking-2507推理模型&#xff0c;這是繼Qwen3-30B-A3B-Instruct-2507后的又一力作。作為專注于推理任務的專用模型&#xff0c;它在數學能力測試AIME25上取得85.0分&#xff0c;超越…

【源力覺醒 創作者計劃】文心一言與deepseek集成springboot開發哪個更方便

一.實驗背景 當前文心一言和deepseek都開源了&#xff0c;二者都可以作為大模型應用開發的模型基礎了&#xff0c;我們都可以編寫springboot項目來集成deepseek和文心一言了 二.實驗目標 本文基于實際操作&#xff0c;通過實際操作來對比文心一言和deepseek在集成到springbo…

核磁共振數據T2幾何均值計算

1、T? 幾何均值公式如下&#xff1a;2、核磁T2幾何均值計算代碼 CSV 文件文件格式&#xff1a; 每一行是一個樣點&#xff08;樣品深度&#xff09;&#xff0c;列為&#xff1a;第一列是“深度”或其他&#xff1b;第二列及以后&#xff08;如 TASPEC0 ~ TASPEC199&#xff0…

微服務架構技巧篇——接口類設計技巧

目錄 一、微服務架構的特點 二、微服務接口類設計技巧 2.1、BFF(Backend For Frontend) 2.1.1、 服務分布式帶來的第一個挑戰導致的幾個典型問題 2.1.2、什么是 BFF 2.1.3、BFF 應用場景 2.1.4、BFF 落地經驗 2.1.4.1、前端負責 BFF 開發優缺點 2.1.4.2、后端負責 BFF 開發優…

C++游戲開發(2)

直接上代碼 1.首先是頭文件編寫 #include <iostream> #include <graphics.h> #include <string> 2,添加畫布 長1280&#xff0c;寬720 initgraph(1280, 720); 3.添加主循環 bool running true; while(runing) { } 4.定義結構體變量msg ExMessge msg; 5.開…

Unity開發2D類銀河惡魔城游戲學習筆記目錄

Unity開發2D類銀河惡魔城游戲學習筆記 Unity教程&#xff08;零&#xff09;Unity和VS的使用相關內容 玩家狀態機 Unity教程&#xff08;一&#xff09;開始學習狀態機 Unity教程&#xff08;二&#xff09;角色移動的實現 Unity教程&#xff08;三&#xff09;角色跳躍的實現…

智慧社區項目開發(三)——基于 Spring Boot 實現動態路由加載:從數據庫到前端菜單的完整方案

在后臺管理系統中&#xff0c;不同用戶角色往往擁有不同的操作權限&#xff0c;對應的菜單展示也需動態調整。動態路由加載正是解決這一問題的核心方案 —— 根據登錄用戶的權限&#xff0c;從數據庫查詢其可訪問的菜單&#xff0c;封裝成前端所需的路由結構并返回。本文將詳細…

Python在自動化與運維領域的核心角色:工具化、平臺化與智能化

&#x1f4dd;個人主頁&#x1f339;&#xff1a;慌ZHANG-CSDN博客 &#x1f339;&#x1f339;期待您的關注 &#x1f339;&#x1f339; 引言 在 IT 系統日益復雜、運維任務持續增長的今天&#xff0c;自動化已成為企業基礎設施管理的關鍵方向。Python 以其簡潔的語法、強大…

RAG實戰指南 Day 28:RAG系統緩存與性能優化

【RAG實戰指南 Day 28】RAG系統緩存與性能優化 開篇 歡迎來到"RAG實戰指南"系列的第28天&#xff01;今天我們將深入探討RAG系統的緩存機制與性能優化策略。在實際生產環境中&#xff0c;RAG系統往往面臨高并發、低延遲的需求&#xff0c;而合理的緩存設計和性能優…

swanlab實驗優雅起名

init中的參數的作用project&#xff1a;整個實驗的名字&#xff1b;experiment_name&#xff1a;在這個實驗中&#xff0c;你的名字是什么&#xff1b; 比如說現在我們要進行對比實驗&#xff0c;PEAN和Triflownet分別是對比方法的名字&#xff0c;這樣的好處是&#xff0c;她們…

Nestjs框架: NestJS 核心機制解析 —— DI(依賴注入)容器與模塊化工作原理

理解 NestJS 的 DI 管理機制 我們想要了解依賴注入&#xff08;Dependency Injection, DI&#xff09;最核心的工作邏輯NestJS 擁有自己的一套 DI 管理系統&#xff0c;它通過一個稱為 DI 容器 的機制&#xff0c;來統一管理應用中所有類&#xff08;class&#xff09;的依賴關…

日語學習-日語知識點小記-構建基礎-JLPT-N3階段(12):文法+單詞

日語學習-日語知識點小記-構建基礎-JLPT-N3階段&#xff08;12&#xff09;&#xff1a;文法單詞 1、前言&#xff08;1&#xff09;情況說明&#xff08;2&#xff09;工程師的信仰2、知識點&#xff11;ーたぶん 多分&#xff12;ーV&#xff08;て&#xff09;いく ? V&…

【趙渝強老師】OceanBase租戶的資源管理

OceanBase數據庫是多租戶的數據庫系統&#xff0c;一個集群內可包含多個相互獨立的租戶&#xff0c;每個租戶提供獨立的數據庫服務。在OceanBase數據庫中&#xff0c;使用資源配置&#xff08;Unit Config&#xff09;、資源單元&#xff08;Unit&#xff09;和資源池&#xff…

8K、AI、低空智聯,H.266能否撐起下一代視頻通路?

一、&#x1f4c8; 爆發式增長的 AI 與視頻數據&#xff1a;智能時代的“數據燃料革命” 隨著生成式 AI、大模型推理、多模態理解等技術的迅猛發展&#xff0c;視頻數據從“記錄工具”轉變為“感知基礎設施”&#xff0c;其在現代智能系統中的戰略地位日益凸顯。 1?? 視頻數…

保姆級別IDEA關聯數據庫方式、在IDEA中進行數據庫的可視化操作(包含圖解過程)

本文以mysql為例&#xff0c;學會了Mysql&#xff0c;其它的數據庫也是類似的模版~如果您覺得這邊文章對你有幫助&#xff0c;可以收藏防止找不到~如果您覺得這篇文章不錯&#xff0c;也感謝您的點贊對我創作的支持1.1 打開側邊欄的Database2.2 選擇要連接的數據庫&#xff08;…