【SpringMVC從入門到精通】00-SpringMVC 簡介

筆記來源:【尚矽谷】SpringMVC教程丨一套快速上手spring mvc

SpringMVC 簡介

1、課程介紹

image-20220313095312928

2、什麼是 MVC?

MVC 是一種軟體架構思想,將軟體分為模型、視圖、控制器三部分

  • M(Model,模型層):處理數據的 JavaBean 類
    • 實體類 Bean:存儲業務數據
    • 業務處理 Bean:Service 或 Dao,處理業務邏輯和數據訪問
  • V(View,視圖層):展示數據的 HTML 頁面,與用戶進行交互
  • C(Controller,控制層):接受請求和響應的 Servlet

MVC 工作流程

  1. 用戶通過視圖層發送請求到伺服器,在伺服器中請求被Controller 接收
  2. Controller 調用相應的 Model 層處理請求
  3. Model 層處理完畢將結果返回到 Controller
  4. Controller 再根據請求處理的結果找到相應的 View 視圖
  5. 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

image-20220313104139012

2)填寫工程名稱、保存為止和 GAV 坐標,點擊 FINISH

image-20220313104207281

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>

根據依賴的傳遞性,相關的依賴也會被導入

image-20220313115336752

4)項目工程結構中添加 web 模組,注意web.xml的路徑要放在src\main\webapp

image-20220313110502676

完成後的目錄結構

image-20220313105817035

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";
}

訪問首頁

image-20220313131435926

2)訪問指定頁面

在主頁index.html創建超鏈接

<a href="/target">訪問指定頁面target.html</a>

但是這種寫法是不行的,可以看到,當滑鼠懸浮在超鏈接上時,左下角的跳轉路徑提示資訊從 8080 下訪問的

這是因為我們是以/開頭的,它分為瀏覽器解析和伺服器解析兩種方式,而超鏈接中的絕對路徑就是由瀏覽器解析的,而不是從上下文路徑訪問

image-20220313133729906

雖然我們可以通過添加上下文的方式實現,因為上下文路徑可以改,所以這種方式肯定是杜絕的

<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";
}

訪問指定頁面

image-20220313133838685

跳轉成功

image-20220313133851794

6、SpringMVC 請求處理底層原理

  • 瀏覽器發送請求,若請求地址符合前端控制器的url-pattern,該請求就會被前端控制器 DispatcherServlet 處理
  • 前端控制器會讀取 SpringMVC 的核心配置文件,通過掃描組件找到控制器,將請求地址和控制器中@RequestMapping註解的value屬性值進行匹配。若匹配成功,該註解所標識的控制器方法就是處理請求的方法
  • 處理請求的方法需要返回一個字元串類型的視圖名稱,該視圖名稱會被視圖解析器解析,加上前綴和後綴組成視圖的路徑,通過 Thymeleaf 對視圖進行渲染,最終轉發到視圖所對應頁面

附錄:SpringMVC 工程創建整體流程

概覽

  • 1)配置pom.xmlweb.xmlspringMVC.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";
    }
}

總結

最後奉上本節導圖,內容僅供參考

00-SpringMVC 簡介