Java面試(2025)—— Spring MVC

什么是Spring MVC

Spring MVC 是 Spring 框架的一個 基于 Java 的 Web 開發模塊,它實現了 MVC(Model-View-Controller)架構模式,用于構建靈活、松耦合的 Web 應用程序。
它是 Spring 生態的核心組件之一,通過簡化 HTTP 請求處理、數據綁定和視圖渲染,幫助開發者高效構建企業級 Web 應用。

Spring MVC的優點

Spring MVC 是 Spring 生態中用于構建 Web 應用的核心模塊,它的核心優勢在于 模塊化設計注解驅動開發,能夠高效處理 HTTP 請求并支持靈活的視圖技術。我個人認為它的主要優點可以從以下幾個方面展開:

(1) 松耦合的模塊化設計

首先,Spring MVC 基于 前端控制器模式DispatcherServlet),將請求分發、業務處理、視圖渲染等職責分離。
這種設計讓各組件(如 ControllerViewResolver)可以獨立替換或擴展,比如從 JSP 切換到 Thymeleaf 只需修改配置,無需改動業務代碼。

(2) 注解驅動的開發效率

其次,它通過 注解(如 @Controller@GetMapping)極大簡化了開發。對比傳統的 Servlet 或 Struts2,代碼量減少 50% 以上,且意圖更清晰。

(3) 強大的數據綁定與驗證

Spring MVC 支持 自動參數綁定(如 @RequestParam@ModelAttribute)和 JSR-303 驗證(如 @Valid)。開發者無需手動解析 HTTP 參數,還能通過 BindingResult 統一處理校驗錯誤,提升代碼健壯性。

(4) 靈活的視圖技術整合

它支持多種視圖技術(JSP、Thymeleaf、Freemarker),并能無縫切換。對于前后端分離項目,還可以直接返回 JSON/XML(通過 @ResponseBody),適應現代開發需求。

(5) 與 Spring 生態深度集成

作為 Spring 的一部分,它可以輕松整合其他組件,比如用 @Transactional 管理事務,或通過 Spring Security 實現權限控制。這種一致性降低了學習成本,也便于維護。

綜上,Spring MVC 特別適合 需要快速開發要求高可維護性 的項目,比如企業級后臺管理系統或 RESTful API。它的靈活性和與 Spring 生態的無縫整合,是許多團隊選擇它的主要原因。

Spring MVC的主要組件

Spring MVC 主要組件

Spring MVC 框架由多個核心組件組成,它們協同工作來處理 HTTP 請求并生成響應。以下是主要組件及其功能:

DispatcherServlet (前端控制器)

  • 核心控制器,負責接收所有請求
  • 將請求委托給其他組件處理
  • 繼承自 HttpServlet

HandlerMapping (處理器映射器)

  • 確定哪個 Controller 應該處理當前請求
  • 默認實現:RequestMappingHandlerMapping
  • 將 URL 映射到對應的處理方法

HandlerAdapter (處理器適配器)

  • 實際調用處理器方法
  • 處理不同類型的處理器
  • 默認實現:RequestMappingHandlerAdapter

Controller (控制器)

  • 處理業務邏輯
  • 返回 ModelAndView 或直接響應
  • 通常使用 @Controller 注解標記

ViewResolver (視圖解析器)

  • 解析邏輯視圖名到實際視圖
  • 常見實現:InternalResourceViewResolver
  • 支持多種視圖技術(JSP, Thymeleaf等)

View (視圖)

  • 負責渲染模型數據
  • 生成最終響應內容(HTML, JSON等)

HandlerExceptionResolver (異常處理器)

  • 處理控制器執行過程中拋出的異常
  • 可以自定義異常處理邏輯

MultipartResolver (文件上傳解析器)

  • 處理 multipart 文件上傳請求
  • 常見實現:CommonsMultipartResolver

什么是DispatcherServlet?

DispatcherServlet 是 Spring MVC 框架的核心組件,它充當了前端控制器的角色,負責協調整個請求處理流程。

主要職責

  1. 請求接收:作為 Servlet,它接收所有的 HTTP 請求
  2. 請求分發:將請求委托給適當的控制器進行處理
  3. 視圖渲染:協調視圖解析和渲染過程
  4. 異常處理:處理請求處理過程中出現的異常
  5. 結果返回:將最終響應返回給客戶端

工作原理

  1. 接收客戶端請求
  2. 查詢 HandlerMapping 確定處理請求的 Controller
  3. 通過 HandlerAdapter 調用實際的 Controller 方法
  4. 處理 Controller 返回的 ModelAndView 或直接響應
  5. 通過 ViewResolver 解析視圖名稱
  6. 渲染視圖并返回響應

什么是Spring MVC框架的控制器?

簡明定義(先給結論)

Spring MVC控制器是處理客戶端請求并返回響應的核心組件,它負責接收用戶請求、協調業務邏輯處理,并決定如何響應客戶端。

核心特性(展示深度)

可以補充以下關鍵點:

  • 注解驅動:主要通過@Controller@RestController注解標識
  • 請求映射:使用@RequestMapping及其變體(@GetMapping等)定義URL映射
  • 多返回值支持:可以返回視圖名稱、ModelAndView、響應體或ResponseEntity
  • 松散耦合:與視圖技術解耦,支持JSP、Thymeleaf等多種視圖
  • REST支持:通過@RestController簡化RESTful API開發

工作流程(結合架構)

在Spring MVC架構中,控制器位于DispatcherServlet之后:

  1. DispatcherServlet接收到請求后
  2. 通過HandlerMapping找到匹配的控制器方法
  3. 方法執行后返回處理結果
  4. 結果經過視圖解析器或消息轉換器處理
  5. 最終生成響應返回客戶端

Spring MVC的控制器是不是單例模式,如果是,有什么問題,怎么解決?

Spring MVC中的控制器默認是單例的(Singleton),這是由Spring容器的默認作用域決定的。在Spring中,所有Bean默認都是單例的,包括使用@Controller@RestController注解的類。

單例模式帶來的潛在問題

  1. 線程安全問題
  • 多個HTTP請求會并發訪問同一個控制器實例
  • 如果控制器有實例變量(成員變量),這些變量會被所有請求共享
  • 可能導致數據混亂或并發修改異常
  1. 狀態保持問題
  • 單例控制器不適合保存請求特定的狀態
  • 例如:在成員變量中存儲請求相關的數據會導致不同請求間的數據污染。

解決方案

1. 避免使用實例變量(推薦)

最佳實踐是控制器中不定義任何實例變量,所有請求特定的數據都應通過方法參數傳遞。

2. 使用方法局部變量

所有請求特定的數據都應在方法內部創建:

請描述Spring MVC的工作流程?描述一下 DispatcherServlet 的工作流程?

時序圖


注意:

  1. HandlerMapping返回的是Hander或者是處理器鏈(處理器+攔截器);
  2. 攔截器執行的三個時機:

(1)適配器調用前執行 (preHandle)

  • 時機:在 HandlerAdapter 調用控制器方法之前
  • 作用:權限校驗、日志記錄、參數預處理等
  • 中斷能力:若任一攔截器的 preHandle 返回 false,后續攔截器和控制器方法均不會執行
  • 順序:按攔截器配置的正序執行

(2)適配器調用后執行 (postHandle)

  • 時機:在 HandlerAdapter 調用控制器方法之后,但在視圖渲染之前
  • 作用:修改模型數據、記錄執行結果等
  • 注意:此時控制器已執行完畢,但響應未寫入客戶端
  • 順序:按攔截器配置的逆序執行;

(3)請求完成后執行 (afterCompletion)

  • 時機:在視圖渲染完成后(整個請求處理完畢時)
  • 作用:資源清理、性能監控統計等
  • 特點:無論請求成功或異常都會執行
  • 順序:按攔截器配置的逆序執行

過濾器和攔截器

特性

過濾器(Filter)

攔截器(Interceptor)

所屬規范

Servlet 規范

Spring MVC 機制

執行位置

DispatcherServlet

DispatcherServlet

依賴

依賴 Servlet 容器

依賴 Spring 容器

可訪問對象

ServletRequest/Response

可以獲取 HandlerMethod 等Spring對象

使用場景

底層請求/響應處理

業務相關的橫切關注點

Spring MVC常用的注解有哪些?

Spring MVC 提供了豐富的注解來簡化 Web 開發,以下是常用注解分類整理

請求映射相關

注解

作用

示例

@RequestMapping

通用請求映射(可指定HTTP方法、頭等)

@RequestMapping(value="/users", method=RequestMethod.GET)

@GetMapping

簡化GET請求映射

@GetMapping("/users/{id}")

@PostMapping

簡化POST請求映射

@PostMapping("/users")

@PutMapping

簡化PUT請求映射

@PutMapping("/users/{id}")

@DeleteMapping

簡化DELETE請求映射

@DeleteMapping("/users/{id}")

@PatchMapping

簡化PATCH請求映射

@PatchMapping("/users/{id}")

參數處理

注解

作用

示例

@RequestParam

獲取URL查詢參數或表單數據

getUser(@RequestParam("name") String username)

@PathVariable

獲取URI模板變量

getUser(@PathVariable Long id)

@RequestBody

接收JSON/XML請求體

createUser(@RequestBody User user)

@RequestHeader

獲取請求頭值

getHeader(@RequestHeader("User-Agent") String agent)

@CookieValue

獲取Cookie值

readCookie(@CookieValue("JSESSIONID") String sessionId)

@ModelAttribute

綁定參數到模型對象

addUser(@ModelAttribute User user) 或 在方法上標注

響應處理

注解

作用

示例

@ResponseBody

將返回值直接寫入HTTP響應體

@ResponseBody User getUser() 或 類上標注@RestController

@ResponseStatus

自定義HTTP響應狀態碼

@ResponseStatus(HttpStatus.CREATED)

@RestController

@Controller + @ResponseBody組合

@RestController public class UserController { ... }

異常處理

注解

作用

示例

@ExceptionHandler

處理控制器內的異常

@ExceptionHandler(UserNotFoundException.class)

@ControllerAdvice

全局異常處理(配合@ExceptionHandler

@ControllerAdvice public class GlobalExceptionHandler { ... }

數據驗證

注解

作用

示例

@Valid

觸發JSR-303驗證

createUser(@Valid @RequestBody User user)

@Validated

Spring的驗證注解(支持分組驗證)

updateUser(@Validated(Group.Update.class) User user)

@NotNull

字段非空校驗(需配合@Valid

@NotNull private String username;

視圖與模型

注解

作用

示例

@Controller

定義控制器類

@Controller public class UserController { ... }

@SessionAttributes

模型屬性存入Session

@SessionAttributes("user")

@CrossOrigin

解決跨域問題

@CrossOrigin(origins = "https://example.com")

其他實用注解

注解

作用

示例

@InitBinder

自定義數據綁定邏輯

@InitBinder public void initBinder(WebDataBinder binder) { ... }

@DateTimeFormat

日期格式轉換

@DateTimeFormat(pattern="yyyy-MM-dd") Date birthDate;

完整代碼示例

關鍵說明:

  1. 組合注解:如@RestController@Controller+@ResponseBody的組合
  2. 參數綁定@RequestParam默認必傳,可通過required=false改為可選
  3. 驗證聯動@Valid需與JSR-303注解(如@NotNull)配合使用
  4. RESTful設計:推薦使用@GetMapping/@PostMapping等簡化注解

掌握這些注解可以覆蓋90%的Spring MVC開發場景!

@Controller注解的作用

@Controller 是 Spring MVC 中最核心的注解之一,用于標記一個類作為控制器(Controller),專門處理 HTTP 請求并返回響應。以下是它的詳細作用解析:

  1. 標識控制器類
    告訴 Spring 容器:當前類是一個 MVC 控制器,需要被掃描并管理其生命周期。
  2. 接收 HTTP 請求
    @RequestMapping 等注解配合,定義處理特定 URL 請求的方法。
  3. 協調模型(Model)和視圖(View)
    在傳統 MVC 模式中,控制器負責處理業務邏輯,返回視圖名稱(如 JSP/Thymeleaf),由視圖解析器渲染。

@RequestMapping注解的作用

@RequestMapping 是 Spring MVC 中最核心的注解之一,用于將 HTTP 請求映射到特定的控制器方法或類上。它提供了靈活的 URL 匹配規則,支持定義請求方法、參數、頭部等條件。以下是詳細解析:

  1. URL 路徑映射
    將 HTTP 請求的 URL 路徑與控制器方法綁定,支持:
  • 精確路徑(如 /users
  • 路徑變量(如 /users/{id}
  • 通配符(如 /resources/**
  1. HTTP 方法約束
    指定處理的請求類型(GET/POST/PUT/DELETE 等)。
  2. 請求參數/頭部過濾
    通過附加條件(如參數必須存在、頭部匹配)進一步篩選請求。

@ResponseBody注解的作用

@ResponseBody 是 Spring MVC 中用于將方法返回值直接寫入 HTTP 響應體的核心注解,通常用于構建 RESTful API 或處理 AJAX 請求。以下是它的詳細解析:

  1. 跳過視圖渲染
    不再通過視圖解析器(如 JSP/Thymeleaf)渲染,而是直接將返回值序列化為 JSON/XML 等格式寫入響應體。
  2. 自動內容協商
    根據請求的
    Accept 頭或 URL 后綴(如 .json),自動選擇合適的 HttpMessageConverter 進行序列化。
  3. 支持多種返回類型
    可返回 Java 對象、集合、字符串等,Spring 會自動處理序列化。

@PathVariable和@RequestParam的區別

@PathVariable@RequestParam 是 Spring MVC 中用于處理 HTTP 請求參數的兩種核心注解,它們的主要區別體現在 參數來源使用場景URL 風格 上。以下是詳細對比:

核心區別總結

特性

@PathVariable

@RequestParam

參數來源

URL 路徑 中提取

URL 查詢字符串 表單數據 中提取

URL 示例

/users/123

/users?id=123

是否必傳

默認必傳(除非指定默認值)

可通過 required=false

設為可選

RESTful 風格

是(推薦用于資源標識)

否(傳統查詢方式)

數據類型轉換

自動(Spring 類型轉換機制)

自動(Spring 類型轉換機制)

使用場景對比

1. @PathVariable(路徑變量)

  • 適用場景:標識 RESTful 資源唯一性(如 ID、用戶名等)
  • 示例代碼
  • URL 風格

2. @RequestParam(請求參數)

  • 適用場景:過濾、排序、分頁等非核心參數
  • 示例代碼
  • URL 風格

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

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

相關文章

天翼云手機斷開連接2小時關機

2025-04-21 天翼云手機斷開連接2小時自動 天翼云手機 4元1個月 天翼云手機永不關機 天翼云手機不休眠 天翼云手機斷開連接時,界面顯示:離線運行,2小時后自動關機 電腦每小時自動連接一次 手機每小時自動連接一次

Redis——數據結構

目錄 1.動態字符串SDS 1.1SDS底層源碼 1.2 SDS動態擴容 1.3動態字符串SDS優點 2.IntSet 2.1底層結構 2.2有序性 2.3.IntSet結構擴容 2.4總結 3.Dict 3.1底層結構 3.2.Dict擴容 3.3Dict收縮 3.4.Dict的rehash 1.分配空間 2. 設置 rehashidx 3. 漸進式 rehash…

C++ GPU并行計算開發實戰:利用CUDA/OpenCL加速粒子系統與流體模擬

🧑 博主簡介:CSDN博客專家、CSDN平臺優質創作者,高級開發工程師,數學專業,10年以上C/C, C#, Java等多種編程語言開發經驗,擁有高級工程師證書;擅長C/C、C#等開發語言,熟悉Java常用開…

LeetCode算法題(Go語言實現)_54

題目 給你兩個正整數數組 spells 和 potions ,長度分別為 n 和 m ,其中 spells[i] 表示第 i 個咒語的能量強度,potions[j] 表示第 j 瓶藥水的能量強度。 同時給你一個整數 success 。一個咒語和藥水的能量強度 相乘 如果 大于等于 success &a…

內網穿透快解析免費開放硬件集成SDK

一、行業問題 隨著物聯網技術的發展,符合用戶需求的智能硬件設備被廣泛的應用到各個領域,而智能設備的遠程運維管理也是企業用戶遇到的問題 二、快解析內網穿透解決方案 快解析是一款內網穿透產品,可以實現內網資源在外網訪問,…

Python+Word實現周報自動化的完整流程

一、技術方案概述 自動化報表解決方案基于以下技術組件: Python 作為核心編程語言python-docx 庫用于處理 Word 文檔pandas 庫用于數據處理和分析matplotlib 或 plotly 庫用于數據可視化Word 模版作為報表的基礎格式 這種方案的優勢在于:保留了 Word 文…

elastic/go-elasticsearch與olivere/elastic

在 Go 語言中,與 Elasticsearch 交互的客戶端庫有多種選擇,其中 github.com/elastic/go-elasticsearch/v8 和 github.com/olivere/elastic/v7 是兩個常用的庫。這兩個庫的功能和用途有一些差異,以下是它們的詳細對比: 1. github.c…

deepseek + kimi制作PPT

目錄 一、kimi簡介二、deepseek生成內容三、生成PPT四、編輯PPT 一、kimi簡介 kimi是一款只能ppt生成器,擅長將文本內容生成PPT。 在這里,??DeepSeek 負責內容生成與邏輯梳理??,??Kimi 優化表達與提供設計建議??。 二、deepseek生…

【八大排序】冒泡、直接選擇、直接插入、希爾、堆、歸并、快速、計數排序

目錄 一、排序的介紹二、排序算法的實現2.1 直接插入排序2.2 希爾排序2.3 直接選擇排序2.4 堆排序2.5 冒泡排序2.6 快速排序2.7 歸并排序2.8 比較排序算法的性能展示2.9 計數排序 個人主頁<— 數據結構專欄<— 一、排序的介紹 我們的生活中有很多排序&#xff0c;比如像…

linux 查詢目錄文件大小

? 在 Linux 系統中&#xff0c;準確地掌握目錄和文件的大小對于磁盤空間管理至關重要。?本文將詳細介紹如何使用 du&#xff08;disk usage&#xff09;命令逐層查看目錄和文件的大小&#xff0c;并結合 sort 命令對結果進行排序&#xff0c;以便有效地識別和管理占用…

如何簡單幾步使用 FFmpeg 將任何音頻轉為 MP3?

在多媒體處理領域&#xff0c;FFmpeg 以其強大的功能和靈活性而聞名。無論是視頻編輯、音頻轉換還是流媒體處理&#xff0c;它都是專業人士和技術愛好者的首選工具之一。在這篇文章中簡鹿辦公將重點介紹如何使用 FFmpeg 進行音頻格式轉換&#xff0c;提供一些常用的轉換方式&am…

通信信號分類識別

通信信號分類識別 AlexNet網絡識別InceptionV3、ResNet-18、ResNet-50網絡識別 采用短時傅里葉變換將一維信號轉換為二維信號&#xff0c;然后采用經典神經網絡進行識別 支持識別BASK,BFSK,BPSK,QPSK,8PSK,QAM和MSK。 AlexNet網絡識別 在這里插入圖片描述 InceptionV3、Re…

TPshop項目-服務器環境部署(部署環境/服務,檢查部署環境/服務,上傳TPshop項目到服務器,配置文件的更改,安裝TPshop)

目錄 部署環境/服務&#xff0c;檢查部署環境/服務 檢查部署環境/服務 上傳TPshop項目到服務器&#xff0c;配置文件的更改&#xff0c;安裝TPshop 部署環境/服務&#xff0c;檢查部署環境/服務 一般部署環境&#xff0c;會根據開發寫的部署文檔來一步一步的部署環境。 部署…

C++入門基礎:命名空間,缺省參數,函數重載,輸入輸出

命名空間&#xff1a; C語言是基于C語言的&#xff0c;融入了面向對象編程思想&#xff0c;有了很多有用的庫&#xff0c;所以接下來我們將學習C如何優化C語言的不足的。 在C/C語言實踐中&#xff0c;在全局作用域中變量&#xff0c;函數&#xff0c;類會有很多&#xff0c;這…

緩存 --- Redis基本數據類型

緩存 --- Redis基本數據類型 Redis Intro5種基礎數據類型 Redis Intro Redis&#xff08;Remote Dictionary Server&#xff09;是一款開源的高性能鍵值存儲系統&#xff0c;常用于緩存、消息中間件和實時數據處理場景。以下是其核心特點、數據類型及典型使用場景&#xff1a; …

Redis命令——list

列表類型是用來存儲多個有序的字符串&#xff0c;列表中的每個字符串稱為元素&#xff08;element&#xff09;&#xff0c;?個列表最多可以存儲個元素 在 Redis 中&#xff0c;可以對列表兩端插入&#xff08;push&#xff09;和彈出&#xff08;pop&#xff09;&#xff0c;…

Android Jetpack Compose 狀態管理解析:remember vs mutableStateOf,有啥不一樣?為啥要一起用?

&#x1f331;《Jetpack Compose 狀態管理解析&#xff1a;remember vs mutableStateOf&#xff0c;有啥不一樣&#xff1f;為啥要一起用&#xff1f;》 在 Jetpack Compose 的世界里&#xff0c;UI 是響應式的。這意味著當狀態發生變化時&#xff0c;UI 會自動重組&#xff0…

使用 PCL 和 Qt 實現點云可視化與交互

下面我將介紹如何結合點云庫(PCL)和Qt框架(特別是QML)來實現點云的可視化與交互功能&#xff0c;包括高亮選擇等效果。 1. 基本架構設計 首先需要建立一個結合PCL和Qt的基本架構&#xff1a; // PCLQtViewer.h #pragma once#include <QObject> #include <pcl/point…

mybatis plus打印sql日志到指定目錄

1、mybatis plus打印sql日志 參考文檔&#xff1a;mybatis plus打印sql日志_mybatisplus日志打印-CSDN博客 2、修改 修改InfoLevelLogger Override public void debug(String s) {// 修改這里logger.info(s);log.debug(s); } 增加&#xff1a;log.debug(s); 修改logback.x…

vue3 watch和watchEffect 的用法和區別

在 Vue 3 里&#xff0c;watch 和 watchEffect 都是用于響應式數據變化的 API&#xff0c;但它們在使用方法和應用場景上存在差異。下面詳細介紹它們的用法和區別。 用法 watch watch 用于監聽特定的響應式數據源&#xff0c;當數據源發生變化時&#xff0c;會執行相應的回調…