【SpringMVC從入門到精通】00-SpringMVC 簡介
- 2022 年 3 月 13 日
- 筆記
- SpringMVC, SpringMVC從入門到精通
SpringMVC 簡介
1、課程介紹
2、什麼是 MVC?
MVC 是一種軟體架構思想,將軟體分為模型、視圖、控制器三部分
- M(Model,模型層):處理數據的 JavaBean 類
- 實體類 Bean:存儲業務數據
- 業務處理 Bean:Service 或 Dao,處理業務邏輯和數據訪問
- V(View,視圖層):展示數據的 HTML 頁面,與用戶進行交互
- C(Controller,控制層):接受請求和響應的 Servlet
MVC 工作流程
- 用戶通過視圖層發送請求到伺服器,在伺服器中請求被Controller 接收
- Controller 調用相應的 Model 層處理請求
- Model 層處理完畢將結果返回到 Controller
- Controller 再根據請求處理的結果找到相應的 View 視圖
- View 視圖渲染數據後最終響應給瀏覽器
3、什麼是 SpringMVC?
SpringMVC 是 Spring 的一個後續產品,是Spring的一個子項目
SpringMVC 是 Spring 為表述層開發提供的一整套完備的解決方案。在表述層框架歷經 Struts、WebWork、Strust2 等諸多產品的歷代更迭之後,目前業界普遍選擇了 SpringMVC 作為 JavaEE 項目表述層開發的首選方案
註:三層架構分為表述層(或表示層)、業務邏輯層、數據訪問層,表述層表示前台頁面和後台 Servlet
4、SpringMVC 的特點
- Spring 家族原生產品:與 IOC 容器等基礎設施無縫對接
- 基於原生的 Servlet:通過了功能強大的前端控制器 DispatcherServlet,對請求和響應進行統一處理
- 全面解決方案:表述層各細分領域需要解決的問題全方位覆蓋
- 程式碼清新簡潔:大幅度提升開發效率
- 即插即用:內部組件化程度高,組件可插撥,想要什麼功能配置相應組件即可
- 性能卓著:尤其適合現代大型、超大型互聯網項目要求
5、HelloWorld
5.1、開發環境
- IDE:idea 2021.1
- 構建工具:maven-3.8.3
- 伺服器:tomcat7
- Spring版本:5.3.16
5.2、創建 Maven 工程
1)新建工程,默認 NEXT
2)填寫工程名稱、保存為止和 GAV 坐標,點擊 FINISH
3)pom.xml
中添加並導入依賴
<dependencies>
<!-- //mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.16</version>
</dependency>
<!-- //mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
<scope>test</scope>
</dependency>
<!-- //mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- //mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring5 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.15.RELEASE</version>
</dependency>
</dependencies>
根據依賴的傳遞性,相關的依賴也會被導入
4)項目工程結構中添加 web 模組,注意web.xml
的路徑要放在src\main\webapp
下
完成後的目錄結構
5.3、配置 web.xml
為什麼要配置web.xml
?註冊 SpringMVC 的前端控制器 DispatcherServlet
1)默認配置方式
此配置作用下,SpringMVC 的配置文件默認位於 WEB-INF 下,默認名稱為<servlet-name>-servlet.xml
例如,以下配置所對應 SpringMVC 的配置文件位於 WEB-INF 下,文件名為springMVC-servlet.xml
<!--配置 SpringMVC 的前端控制器,對瀏覽器發送的請求統一進行處理-->
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<!--
設置 SpringMVC 的核心控制器所能處理的請求的請求路徑
/ 所匹配的請求可以是 /login 或 .html 或 .js 或 .css 方式的請求路徑
但是 / 不能匹配 .jsp 請求路徑的請求
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
默認配置方式對位置和名稱都是默認的,這樣並不好!Maven 工程配置文件應該統一放置在resources
下,應該如何來實現呢?來看下面的「擴展配置方式」
2)擴展配置方式
- 通過
init-param
標籤設置 SpringMVC 配置文件的位置和名稱 - 通過
load-on-startup
標籤設置 SpringMVC 前端控制器 DispatcherServlet 的初始化時間
<!--配置 SpringMVC 的前端控制器,對瀏覽器發送的請求統一進行處理-->
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--通過初始化參數指定SpringMVC配置文件的位置和名稱-->
<init-param>
<!--contextConfigLocation 為固定值-->
<param-name>contextConfigLocation</param-name>
<!--使用 classpath: 表示從類路徑查找配置文件,java 工程默認src下,maven 工程默認 src/main/resources 下-->
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<!--
作為框架的核心組件,在啟動過程中有大量的初始化操作要做
而這些操作放在第一次請求時才執行會嚴重影響訪問速度
將前端控制器 DispatcherServlet 的初始化時間提前到服務啟動時
-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<!--
設置 SpringMVC 的核心控制器所能處理的請求的請求路徑
/ 所匹配的請求可以是 /login 或 .html 或 .js 或 .css 方式的請求路徑
但是 / 不能匹配 .jsp 請求路徑的請求
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
註:
<url-pattern>
標籤中使用/
和/*
的區別:
/
所匹配的請求可以是/login
或.html
或.js
或.css
方式的請求路徑,但是/
不能匹配.jsp
請求路徑的請求因此就可以避免在訪問
.jsp
頁面時,該請求被 DispatcherServlet 處理,從而找不到相應的頁面的情況
/*
則能夠匹配所有請求,例如在使用過濾器時,若需要對所有請求進行過濾,就需要使用/*
的寫法
5.4、創建請求控制器
由於前端控制器對瀏覽器發送的請求進行了統一的處理,但是具體的請求有不同的處理過程,因此需要創建處理具體請求的類,即請求控制器
請求控制器中每一個處理請求的方法稱為控制器方法
因為 SpringMVC 的控制器由一個 POJO(普通 Java 類)擔任,因此需要通過@Controller
註解將其標識為一個控制層組件,交給 Spring 的 IOC 容器管理,此時 SpringMVC 才能夠識別控制器的存在
@Controller
public class HelloController {
}
5.5、創建 SpringMVC 配置文件
<!--自動掃描包-->
<context:component-scan base-package="com.vectorx.springmvc"></context:component-scan>
<!--配置Thymeleaf視圖解析器-->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!--視圖前綴-->
<property name="prefix" value="/WEB-INF/templates/"/>
<!--視圖後綴-->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
5.6、測試
1)訪問首頁
創建首頁index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首頁</title>
</head>
<body>
<h1>首頁</h1>
</body>
</html>
在請求控制器中創建處理請求的方法
//@RequestMapping 註解:處理請求和控制器方法之間的映射關係
//@RequestMapping 註解的 value 屬性可以通過請求地址匹配請求,/ 表示的當前工程的上下文路徑
// localhost:8080/springMVC/
@RequestMapping("/")
public String index() {
//返回視圖名稱
return "index";
}
訪問首頁
2)訪問指定頁面
在主頁index.html
創建超鏈接
<a href="/target">訪問指定頁面target.html</a>
但是這種寫法是不行的,可以看到,當滑鼠懸浮在超鏈接上時,左下角的跳轉路徑提示資訊從 8080 下訪問的
這是因為我們是以/
開頭的,它分為瀏覽器解析和伺服器解析兩種方式,而超鏈接中的絕對路徑就是由瀏覽器解析的,而不是從上下文路徑訪問
雖然我們可以通過添加上下文的方式實現,因為上下文路徑可以改,所以這種方式肯定是杜絕的
<a href="/SpringMVC/target">訪問指定頁面target.html</a>
那應該如何處理呢?這裡就可以使用thymeleaf
來動態獲取上下文路徑
- 首先需要在
<html>
標籤中引入thymeleaf
的命名空間xmlns:th="//www.thymeleaf.org"
- 然後使用
th:
前綴修飾標籤屬性,這裡使用th:href
來修飾<a>
標籤的<href>
屬性 - 最後
th:href
中的屬性值中包裹一層@{}
,這裡值為@{/target.html}
<!DOCTYPE html>
<html lang="en" xmlns:th="//www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首頁</title>
</head>
<body>
<h1>首頁</h1>
<a th:href="@{/target}">訪問指定頁面target.html</a>
</body>
</html>
同時,後台請求控制器也要加上對target
請求進行處理的控制器方法
@RequestMapping("/target")
public String toTarget() {
return "target";
}
訪問指定頁面
跳轉成功
6、SpringMVC 請求處理底層原理
- 瀏覽器發送請求,若請求地址符合前端控制器的
url-pattern
,該請求就會被前端控制器 DispatcherServlet 處理 - 前端控制器會讀取 SpringMVC 的核心配置文件,通過掃描組件找到控制器,將請求地址和控制器中
@RequestMapping
註解的value
屬性值進行匹配。若匹配成功,該註解所標識的控制器方法就是處理請求的方法 - 處理請求的方法需要返回一個字元串類型的視圖名稱,該視圖名稱會被視圖解析器解析,加上前綴和後綴組成視圖的路徑,通過 Thymeleaf 對視圖進行渲染,最終轉發到視圖所對應頁面
附錄:SpringMVC 工程創建整體流程
概覽
- 1)配置
pom.xml
、web.xml
、springMVC.xml
- 2)創建前台頁面和後台請求控制器
詳解
1)添加pom.xml
依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="//maven.apache.org/POM/4.0.0"
xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="//maven.apache.org/POM/4.0.0 //maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.vectorx</groupId>
<artifactId>springmvc-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.16</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.15.RELEASE</version>
</dependency>
</dependencies>
</project>
2)創建web.xml
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="//xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="//xmlns.jcp.org/xml/ns/javaee //xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3)創建springMVC.xml
配置文件
<context:component-scan base-package="com.vectorx.springmvc"></context:component-scan>
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/"/>
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
4)創建前台頁面
index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="//www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首頁</title>
</head>
<body>
<h1>首頁</h1>
<a th:href="@{/target}">訪問指定頁面target.html</a>
</body>
</html>
target.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HelloWorld</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
5)創建Controller
請求控制器
@Controller
public class HelloController {
@RequestMapping("/")
public String index() {
//返回視圖名稱
return "index";
}
@RequestMapping("/target")
public String toTarget() {
return "target";
}
}
總結
最後奉上本節導圖,內容僅供參考