目錄
一、引言
二、MVC 模式:SpringMVC 的設計基石
2.1 MVC 三大組件
2.2 主流 MVC 框架對比
2.3 MVC 模式的核心優勢
三、SpringMVC 框架:是什么?為什么學?
3.1 什么是 SpringMVC?
3.2 為什么要學 SpringMVC?(對比原生 Servlet)
四、SpringMVC 執行流程:從請求到響應的完整鏈路
4.1 核心組件(無需手動開發,框架提供)
4.2 完整執行流程(圖文解析)
五、注解開發 SpringMVC:手把手搭建入門程序
5.1 前置準備
5.2 步驟 1:創建 Maven Web 項目
5.3 步驟 2:添加依賴(pom.xml)
5.4 步驟 3:配置前端控制器(web.xml)
5.5 步驟 4:編寫 SpringMVC 核心配置(springmvc.xml)
5.6 步驟 5:開發控制器(Controller)
5.7 步驟 6:開發視圖頁面
5.8 步驟 7:測試程序
六、入門常見問題解決
6.1 URL 攔截規則:/?vs?/*?的區別
6.2 POST 請求參數亂碼
七、第一篇總結
一、引言
????????在 Java Web 開發中,MVC 設計模式是實現代碼解耦、提高項目可維護性的核心思想,而SpringMVC作為 Spring 生態體系下的 MVC 框架,憑借其與 Spring 的無縫集成、靈活的配置和簡潔的開發風格,早已取代 Struts2 成為主流選擇。本文作為系列博客的第一篇,將從 MVC 模式基礎入手,帶你理解 SpringMVC 的核心定位、執行流程,并手把手教你搭建第一個注解驅動的 SpringMVC 入門程序。
二、MVC 模式:SpringMVC 的設計基石
????????在學習 SpringMVC 前,必須先掌握 MVC 模式的核心思想 —— 它將應用程序分為三個獨立部分,實現 “職責分離”。
2.1 MVC 三大組件
- Model(模型):分為 “業務模型” 和 “數據模型”。業務模型封裝業務邏輯(如用戶登錄校驗、訂單計算),數據模型封裝數據(如 User、Order 實體類),是應用程序的 “數據與邏輯核心”。
- View(視圖):負責數據展示,即用戶看到的界面(如 JSP、HTML、Freemarker),僅關注 “如何顯示數據”,不處理業務邏輯。
- Controller(控制器):作為 “中間樞紐”,接收用戶請求,調用 Model 處理業務,再將處理結果傳遞給 View 展示,實現 View 與 Model 的解耦。
2.2 主流 MVC 框架對比
框架 | 特點 | 適用場景 |
---|---|---|
SpringMVC | 與 Spring 無縫集成、注解驅動、輕量靈活 | 中大型企業級項目(主流) |
Struts2 | 功能全面但配置復雜、性能略低 | 傳統項目(逐漸被淘汰) |
JFinal | 輕量級、API 簡潔、開發效率高 | 小型項目或快速原型開發 |
2.3 MVC 模式的核心優勢
- 解耦:View 與 Model 分離,同一業務邏輯可對應多個視圖(如 PC 端、移動端頁面)。
- 可維護性:各組件職責單一,修改視圖不影響業務邏輯,修改業務不影響視圖。
- 可擴展性:新增功能只需新增 Controller 或 Model,無需改動現有視圖。
三、SpringMVC 框架:是什么?為什么學?
3.1 什么是 SpringMVC?
- 定位:SpringMVC 是 Spring Framework 的子框架,本質是對 Servlet 的封裝,解決了原生 Servlet 的痛點(如請求映射繁瑣、參數接收復雜)。
- 核心特性:
- 注解驅動:通過
@Controller
、@RequestMapping
等注解,讓普通 POJO 成為控制器,無需實現接口。 - 松散耦合:支持可插拔組件(如視圖解析器、參數綁定組件),擴展性強。
- 無縫集成 Spring:可直接使用 Spring 的 IOC、AOP 等功能(如依賴注入 Service 層)。
- 易測試:支持 Web 層單元測試,無需啟動服務器即可測試控制器。
- 注解驅動:通過
3.2 為什么要學 SpringMVC?(對比原生 Servlet)
原生 Servlet 開發存在三大痛點,而 SpringMVC 完美解決:
- 請求映射繁瑣:100 個請求需寫 100 個 Servlet,即使合并 Servlet 也需手動判斷請求路徑,耦合度高;SpringMVC 通過
@RequestMapping
一鍵綁定 URL。 - 參數接收復雜:需手動調用
request.getParameter("username")
獲取參數,還需手動類型轉換(如 String 轉 Integer);SpringMVC 自動完成參數綁定與類型轉換。 - 解耦不足:Servlet 與業務邏輯代碼耦合,難以維護;SpringMVC 通過 Controller 調用 Service,層次清晰。
四、SpringMVC 執行流程:從請求到響應的完整鏈路
SpringMVC 的執行流程依賴其核心組件的協作,理解流程是掌握框架的關鍵。
框架處理流程圖:
4.1 核心組件(無需手動開發,框架提供)
- 前端控制器(DispatcherServlet):全局入口,接收所有請求,轉發給其他組件處理,降低組件耦合。
- 處理器映射器(HandlerMapping):根據請求 URL 查找對應的 “處理器(Controller 方法)”,返回 HandlerExecutionChain(包含處理器和攔截器)。
- 處理器適配器(HandlerAdapter):適配不同類型的處理器(如注解式、接口式),調用處理器的業務方法。
- 處理器(Handler/Controller):開發者編寫的 Controller 類,封裝業務邏輯,返回 ModelAndView(模型數據 + 邏輯視圖名)。
- 視圖解析器(ViewResolver):將 “邏輯視圖名”(如 "ok.jsp")解析為 “物理視圖”(如
/WEB-INF/jsp/ok.jsp
)。 - 視圖(View):開發者編寫的 JSP/HTML,渲染 Model 中的數據并響應給用戶。
4.2 完整執行流程(圖文解析)
- 用戶發送請求(如
http://localhost:8080/reg.do
),請求被DispatcherServlet攔截。 - DispatcherServlet 調用HandlerMapping,根據 URL 找到對應的 Controller 方法(如
UserController
的show()
方法)。 - DispatcherServlet 調用HandlerAdapter,適配并調用找到的 Controller 方法。
- Controller 方法執行業務邏輯,返回ModelAndView(如模型數據
uname=張三
,邏輯視圖名ok.jsp
)。 - DispatcherServlet 調用ViewResolver,將邏輯視圖名
ok.jsp
解析為物理視圖路徑(如/ok.jsp
)。 - ViewResolver 返回 View 對象,DispatcherServlet 調用 View 的
render()
方法,渲染 Model 數據到視圖。 - 渲染完成后,DispatcherServlet 將響應結果返回給用戶,流程結束。
五、注解開發 SpringMVC:手把手搭建入門程序
????????本節將基于 IDEA+Maven+Tomcat,實現一個 “用戶注冊” 功能,涵蓋環境搭建、配置編寫、控制器開發全流程。
5.1 前置準備
- IDEA 版本:需旗艦版(Community 版不支持 Web 開發),下載地址:JetBrains IDEA。
- Tomcat 配置:
- 解壓 Tomcat 到本地(如
D:\Tomcat8.5
)。 - IDEA 中依次點擊:
Run → Edit Configurations → Templates → Tomcat Server → Local → Configure
,選擇 Tomcat 解壓路徑。 - 新建 Tomcat 配置:點擊
+ → Tomcat Server → Local
,設置 Name(如 Tomcat8.5),在Deployment
中添加項目的war exploded
包。
- 解壓 Tomcat 到本地(如
5.2 步驟 1:創建 Maven Web 項目
- 新建項目:
New Project → Maven → 勾選Create from archetype → 選擇org.apache.maven.archetypes:maven-archetype-webapp
。 - 填寫項目信息:GroupId(如
com.jr
)、ArtifactId(如springmvc-demo
)、Version(如1.0-SNAPSHOT
)。 - 補全目錄:項目創建后,手動在
src/main
下添加java
(標記為 Sources Root)和resources
(標記為 Resources Root)目錄。
5.3 步驟 2:添加依賴(pom.xml)
需引入 Spring 核心包、SpringMVC 包、Servlet/JSP 包、JSTL 包,完整依賴如下:
<dependencies><!-- JUnit測試 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><!-- Spring核心包 --><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>4.1.6.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>4.1.6.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.1.6.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>4.1.6.RELEASE</version></dependency><!-- SpringMVC包 --><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>4.1.6.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>4.1.6.RELEASE</version></dependency><!-- Servlet/JSP依賴 --><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.3</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.2</version><scope>provided</scope></dependency><!-- JSTL標簽庫 --><dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version></dependency>
</dependencies>
5.4 步驟 3:配置前端控制器(web.xml)
前端控制器是 SpringMVC 的入口,需在WEB-INF/web.xml
中配置,核心作用是攔截請求并轉發:
<web-app version="2.5"xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><!-- 歡迎頁 --><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list><!-- 配置SpringMVC前端控制器 --><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 指定SpringMVC配置文件路徑(默認在WEB-INF/[servlet-name]-servlet.xml) --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param><!-- 啟動Tomcat時自動加載Servlet --><load-on-startup>1</load-on-startup></servlet><!-- 攔截規則:/ 表示攔截所有請求(除JSP外) --><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!-- 配置亂碼過濾器(解決POST請求參數亂碼) --><filter><filter-name>charsetFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>charsetFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
</web-app>
5.5 步驟 4:編寫 SpringMVC 核心配置(springmvc.xml)
在src/main/resources
下創建springmvc.xml
,配置注解掃描、注解驅動等核心功能:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 1. 掃描Controller注解(指定包路徑) --><context:component-scan base-package="com.jr.controller"/><!-- 2. 開啟注解驅動:自動加載處理器映射器、處理器適配器 --><mvc:annotation-driven/><!-- 3. 靜態資源放行(如JS、CSS、圖片,避免被DispatcherServlet攔截) --><mvc:resources location="/js/" mapping="/js/**"/><mvc:resources location="/images/" mapping="/images/**"/>
</beans>
5.6 步驟 5:開發控制器(Controller)
在src/main/java/com/jr/controller
下創建UserController
,使用@Controller
標記為控制器,@RequestMapping
綁定請求路徑:
package com.jr.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;@Controller // 標記此類為SpringMVC控制器
public class UserController {// 綁定請求路徑:http://localhost:8080/reg.do@RequestMapping("reg.do")public ModelAndView register(HttpServletRequest request) {// 1. 創建ModelAndView對象(封裝模型數據和視圖名)ModelAndView mv = new ModelAndView();// 2. 接收請求參數(此處用原生Servlet API,后續會優化)String username = request.getParameter("username");String password = request.getParameter("password");// 3. 封裝模型數據(存入request作用域,供視圖使用)mv.addObject("uname", username); // 等價于request.setAttribute("uname", username)// 4. 指定邏輯視圖名(視圖解析器會解析為物理路徑)mv.setViewName("ok.jsp");return mv;}
}
5.7 步驟 6:開發視圖頁面
注冊頁面(index.jsp):在webapp
下創建,提供用戶輸入表單:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>用戶注冊</title>
</head>
<body>
<form action="reg.do" method="post">用戶名:<input type="text" name="username"><br>密碼:<input type="password" name="password"><br><input type="submit" value="提交注冊">
</form>
</body>
</html>
成功頁面(ok.jsp):在webapp
下創建,展示注冊成功信息:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>注冊成功</title>
</head>
<body>
<h3>注冊成功!歡迎您,${uname}!</h3> <!-- EL表達式獲取模型數據 -->
</body>
</html>
5.8 步驟 7:測試程序
- 啟動 Tomcat,訪問
http://localhost:8080/springmvc-demo/
(項目上下文路徑根據配置調整)。 - 輸入用戶名和密碼,點擊 “提交注冊”,頁面跳轉至
ok.jsp
并顯示歡迎信息,說明程序運行成功。
六、入門常見問題解決
6.1 URL 攔截規則:/
?vs?/*
?的區別
/
:攔截所有請求(除 JSP 外),是 SpringMVC 推薦配置。JSP 由 Tomcat 的 JspServlet 處理,不會被攔截,可正常渲染。/*
:攔截所有請求(包括 JSP),會導致 JSP 被 DispatcherServlet 當作控制器處理,找不到對應映射而報 404 錯誤,禁止使用。
6.2 POST 請求參數亂碼
????????如步驟 3 中配置的CharacterEncodingFilter
,通過encoding=UTF-8
強制設置請求和響應的字符編碼,解決 POST 亂碼問題(GET 亂碼需修改 Tomcat 的server.xml
,添加URIEncoding="UTF-8"
)。
七、第一篇總結
????????本文從 MVC 模式基礎出發,講解了 SpringMVC 的核心定位、執行流程,并通過 “用戶注冊” 案例完整演示了注解開發的入門流程。你已掌握:
- MVC 模式的三大組件與職責分離思想;
- SpringMVC 的核心特性與執行流程;
- 基于 Maven+IDEA 的 SpringMVC 環境搭建;
- 控制器開發與請求映射、視圖跳轉的基本用法。
????????下一篇博客將深入 SpringMVC 的核心功能,講解請求映射、返回值類型與參數綁定,帶你實現更靈活的業務邏輯開發。