Spring MVC學習隨筆-第一個Spring MVC程式(父子項目結構、Tomcat配置、ViewResolver)

来源:https://www.cnblogs.com/eyewink/archive/2023/11/26/17856617.html
-Advertisement-
Play Games

主要介紹了第一個Spring MVC程式的環境搭建、父子項目結構、Tomcat配置、配置文件。對DispatcherServlet的講解,2個核心類型:1.RequestMappingHandlerMapping 2.RequestMappingHandlerAdapter,視圖解析器ViewRes... ...


學習視頻:孫哥說SpringMVC:結合Thymeleaf,重塑你的MVC世界!|前所未有的Web開發探索之旅

第二章、第一個SpringMVC程式的開發

2.1開發版本

  1. JDK1.8+
  2. Maven3.6+
  3. IDEA2021+
  4. SpringFramework 5.1.4
  5. Tomcat8.5.29
  6. MySQL5.7.18

按照父子項目的結構,管理和創建項目,創建一個空Project作為父項目,pom文件如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.baizhi</groupId>
    <artifactId>baizhi-mvc-parent</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>baizhi-mvc-01</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

創建子項目Module:

子項目pom文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>baizhi-mvc-parent</artifactId>
        <groupId>com.baizhi</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>baizhi-mvc-01</artifactId>
    <packaging>war</packaging>

註意:初次創建web項目時,WEB-INF包下的web.xml引入的servlet規範的版本還是2.3,而我們使用的tomcat8至少需要3.0以上的規範,所以需要修複,刪除此文件後在Project Settings設置,如圖:

Tomcat配置

2.2 環境搭建

2.2.1 引入相關jar

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.27</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.1</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>5.3.27</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.27</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.27</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.3.27</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>5.3.27</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.3.27</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.1.1</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.19</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.13</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.27</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>5.3.27</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.8</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.3</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.36</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.12</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>1.2.12</version>
    </dependency>
    <dependency>
        <groupId>org.logback-extensions</groupId>
        <artifactId>logback-ext-spring</artifactId>
        <version>0.1.5</version>
    </dependency>
    <dependency>
        <groupId>org.yaml</groupId>
        <artifactId>snakeyaml</artifactId>
        <version>1.30</version>
    </dependency>
</dependencies>

註意:SpringMVC比前面所學習的Spring,就多引入了一個jar包,叫做spring-webmvc.jar

2.2.2 配置文件

SpringMVC的配置文件,就是Spring的配置文件

註意事項:

  1. 名字可以隨便命名,本次課程取名dispatcher.xml
  2. 放置路徑可以根據需要,隨意放置,本次課程放置在資源文件夾的根下.

2.2.3 初始化配置

  • web.xml
<!--
 alt+insert快捷鍵引入Spring提供的dispatcherServlet-->
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <!-- 整個SpringMVC的核心-->
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--指定SpringMVC配置文件的路徑-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:dispatcher.xml</param-value>
    </init-param>
    <!--本Servlet會在tomcat啟動時創建-->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
  1. DispatcherServlet稱為前端控制器(中央控制器)
  2. DispatcherServlet的核心作用:
    1. 用於創建Spring的工廠(容器)

      等效於:ApplicationContext ctx = new ClassPathXmlApplicationContext(”dispatcher.xml”);
      因為DispatcherServlet封裝的Spring工廠只能讀取xml,所以無法遷移到純註解編程

    2. 控制SpringMVC內部的運行流程

SpringMVC的配置文件dispatcher.xml

<!--設置註解掃描的路徑-->
    <context:component-scan base-package="com.baizhi"/>

    <!--引入SpringMVC的核心功能-->
    <mvc:annotation-driven/>

mvc:annotaion-driven這段配置的主要作用:引入SpringMVC的核心功能

主要引入了2個核心類型:1.RequestMappingHandlerMapping 2.RequestMappingHandlerAdapter

  1. RequestMappingHandlerMapping實現了HandlerMapping介面

    它會處理@RequestMapping註解,並將其註冊到請求映射表中

  2. RequestMappingHandlerAdapter實現了 HandlerAdapter介面

    它是處理請求的適配器,確定調用某個符合要求的控制器類中具體服務的方法

SpringMVC對mvc:annotaion-driven的封裝

context:component-scan

  1. 進行註解掃描

  2. DispatcherServlet所創建的工廠需要讀取XML的配置文件,不能使用純註解的開發。所以目前使用Spring配置文件+基礎註解的形式,進行開發

    基礎註解可以用:@Component @Service @Repository,@Controller,@Scope,@Transsactional等

    高級註解無效:@Configuration,@Bean,@ComponentScan

2.3編程思路

2.3.1 思路分析

基本流程

  1. 開發一個類在上面加入@Controller註解
  2. 提供一個控制器方法:參數是HttpServletRequest,HttpServletResponse,返回值是String的,同時加入@RequestMapping註解定義請求路徑
  3. 在控制方法中,完成核心開發功能,把對應JSP頁面的路徑,作為方法的返回值返回

2.3.2 編碼

@Controller
public class FirstController {

    @RequestMapping("/first")
    public String first(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("FirstController.first");
        return "/result.jsp";
    }
}
必須要進行@Controller註解的掃描,配置文件中:<context:component-scan base-package="com.baizhi"/>

2.3.3 一個控制器中,提供多個服務方法

  • Servlet作為控制器,一個類中只能提供一個服務方法

    在原來的Servlet開發中,明確控制器的方法必須實現介面規定的service(HttpServletRequest request, HttpServletResponse response)方法,一個類中只能實現一次,所以一個類中只能有一個服務方法

  • SpringMVC的控制器,一個類中可以提供多個對外服務的方法

    1. SpringMVC控制器,沒有對於方法名的限制,所以可以提供多個服務方法
      http://localhost:8989/basic/first
      http://localhost:8989/basic/second
      @Controller
      public class FirstController {
      
          @RequestMapping("/first")
          public String first(HttpServletRequest request, HttpServletResponse response) {
              System.out.println("FirstController.first");
              return "/result.jsp";
          }
          @RequestMapping(value="/second")
          public String second(HttpServletRequest request, HttpServletResponse response) {
              System.out.println("FirstController.second");
              return "/result.jsp";
          }
      }
      

2.3.4 註意

SpringMVC中我們開發的Controller,也稱之為Handler(SpringMVC內部的叫法)

2.4 第一個程式的細節分析

2.4.1 一種類型的SpringMVC控制器被創建幾次?

  1. 回顧:Servlet控制器被創建的次數

    一種類型的Servlet,只會被Tomcat創建一次,所以Servlet是單實例。

  2. Servlet是單實例並不是單例設計模式

  3. SpringMVC的控制器被Spring創建的次數

    控制器創建的次數,是由@Scope註解決定的,可以是一次也可以是多次

  4. 預設情況下SpringMVC的控制器只會被創建一次,會存線上程安全的問題

2.4.2@RequestMapping註解

核心作用:為控制器方法提供外部訪問的url路徑

http://localhost:8989/basic/first

@RequestMappring(”/first”)
public String first(HttpServletRequest request, HttpServletResponse response)

  • 路徑分隔符 /可以省略

    @RequestMapping(value="suns/second")
    public String second(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("FirstController.second");
        return "/result.jsp";
    }
    # 註意 多級目錄開頭可以不寫/
    
  • 在一個控制器方法上映射多個路徑

    @Controller
    public class FirstController {
        @RequestMapping(**value={"first","third"}**)
        public String first(HttpServletRequest request, HttpServletResponse response) {
            System.out.println("FirstController.first");
            return "/result.jsp";
        }
    }
    
  • Controller類上加入@RequestMapping註解

    http://localhost:8989/basic/user/first
    http://localhost:8989/basic/user/second
    @Controller
    @RequestMapping("/user")
    public class FirstController {
    
        @RequestMapping("/addUser")
        public String addUser(HttpServletRequest request, HttpServletResponse response) {
            System.out.println("FirstController.addUser");
            return "/result.jsp";
        }
        @RequestMapping(value="/deleteUser")
        public String deleteUser(HttpServletRequest request, HttpServletResponse response) {
    	        System.out.println("FirstController.deleteUser");
            return "/result.jsp";
        }
    }
    

設計目的

滿足單一職能原則,可以更好的按照功能,進行不同模塊的區分,有利於項目的管理。

  • @RequestMapping限定用戶的請求方式
    • 請求方式

      1. 所謂請求方式指的就是Web開發中的 POST請求與GET請求

        回顧:Web開發中的POST請求與GET請求的區別

      兩種請求提交數據的區別

      1. GET請求:通過請求行(地址欄)提交數據(QueryString),明文數據提交,不安全,提交的數據量小(不超過2048位元組)
      2. POST請求:通過請求體提交數據,密文提交(不是加密,指的是一般用戶不可見),相對安全,提交數據量大(理論上沒有限制)

兩種請求發起方式的區別

  • RequestMapping如何限定用戶的請求方式

    1. 預設情況下:@RequestMapping註解接受所有請求方式的訪問(Post、Get、…

    2. 通過@RequestMapping的參數可以限定某個控制器方法只接受特定的請求方式

      @RequestMapping(value = "/m1",method = {RequestMethod.POST})

    3. 可以同時限定多種請求方式的訪問

      @RequestMapping(value = "/m1",method = {RequestMethod.POST,RequestMethod.GET})

    4. 當用戶發起了@RequestMapping不支持的請求操作

      SrpingMVC在伺服器端拋出一個405錯誤 Method Not Allowed

  • Http協議中其他的請求方式【瞭解】

    1. 除常規的POST、GET請求外,Http協議還提供了其他的請求方式:PUT、DELETE、OPTIONS….
    2. @RequestMapping註解,預設情況也支持其他請求方式的訪問,同時也可以根據需要進行限定
    3. 除POST、GET這2種請求方式外,其他的請求方式在瀏覽器支持的不好,所以可以使用專屬工具(PostMan)或者庫進行測試
    4. 其他的請求方式,大多數不支持響應視圖技術(JSP,Thymeleaf),只能返回簡單字元串或者JSON數據

2.4.3 控制器方法參數

SpringMVC在控制器方法參數設計的過程中,非常靈活,可以支持多種參數的設置方式,非常強大,它也把這種設計,叫做數據綁定。可以設置無參,也可以設置多個參數

  • 代碼

    
    @RequestMapping("first")
    public String first(HttpServletRequest request, HttpServletResponse response)
    
    @RequestMapping("first")
    public String first(HttpServletRequest request)
    
    @RequestMapping("first")
    public String first(HttpServletResponse response)
    
    @RequestMapping("first")
    public String first(HttpServletRequest request, HttpServletResponse response, HttpSession session)
    
    @RequestMapping("first")
    public String first()
    
    註意:HttpSession也可以單獨使用 或者 組合使用
    			ServletContext(application) 不能應用在控制器方法中 做形參
    獲取方法:session.getServletContext();
    					request.getSession().getServletContext();
    

    思考:上述五種代碼形式,在後續開發中最常用哪種?

        前四種不推薦的原因:與Servlet API存在耦合
    

    第五種不推薦的原因:無法接受client的請求參數

2.4.4 視圖解析器(頁面跳轉)

  • 目前頁面跳轉存在的問題

    控制器中的跳轉路徑與實際視圖路徑存在耦合

  • 視圖解析器ViewResolver

    通過視圖解析器可以解決跳轉路徑的耦合

    視圖解析器將首碼(路徑)和尾碼(文件類型)進行封裝,跟返回的頁面Name進行拼接,因此能訪問,並解耦合

    @Controller
    @RequestMapping("/view")
    public class ViewController {
        @RequestMapping("m1")
        public String m1(HttpSession session) {
            System.out.println("session = " + session);
            return "result";
        }
    }
    

    配置文件:

    註解開發

    @Configuration
    public class AppConfig {
    
        @Bean
        public InternalResourceViewResolver viewResolver() {
            InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
            viewResolver.setPrefix("/");
            viewResolver.setSuffix(".jsp");
            return viewResolver;
        }
    }
    
    **註意:
    		1. AppConfig配置Bean應該放置到<context:component-scan/>掃描的路徑下
    		2.結合前面所講,目前因為DispatcherServlet封裝的Spring工廠(容器)只能讀取xml,所以無法進行純註解替換。**
    

    2.4.5 SpringMVC配置文件的預設設置【瞭解】

作者:揚眉劍出鞘
出處: https://www.cnblogs.com/eyewink/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在今天的課上,我們深入討論了封裝、反射和單例模式這幾個重要的概念。我不想過多地贅述它們的細節,但是請大家務必記住它們的基本語法規則,因為這也是面向對象章節的結束。我希望大家能夠牢牢掌握這些知識點,為未來的學習打下堅實的基礎。 ...
  • 在Web應用中,表單處理是一個基本而常見的任務。Python的WTForms庫通過提供表單的結構、驗證和渲染等功能,簡化了表單的處理流程。與此同時,Flask的擴展Flask-WTF更進一步地整合了WTForms,為開發者提供了更便捷、靈活的表單處理方式。Flask-WTF是建立在WTForms之上... ...
  • 1 簡介 谷歌文檔是一種協作文檔編輯服務。 協作文檔編輯服務可以通過兩種方式設計: 設計為C/S架構的集中式設施,為所有用戶提供文檔編輯服務 使用點對點技術設計,以便在單個文檔上協作 大多數商業解決方案側重於客戶端服務體繫結構,以實現更精細的控制。因此,我們將關註使用客戶端服務體繫結構設計服務。讓我 ...
  • Jinja2,由Flask框架的創作者開發,是一款功能豐富的模板引擎,以其完整的Unicode支持、靈活性、高效性和安全性而備受推崇。最初受Django模板引擎啟發,Jinja2為Flask提供了強大的模板支持,後來也成為其他項目的首選。在本文中,我們將深入探討Jinja2的特性、語法以及如何在Fl... ...
  • 類應該是被封裝的,類的用戶通過介面使用類提供的功能,而不必關心類的內部如何實現。然而,C++標準庫容器 std::vector 的實現滲透到了介面中來。對於以下代碼: const int pushNum = 10; std::vector<int> v = { 1,2,3 }; int* p = & ...
  • Bug1 自定義被限流的後續操作@SentinelResource(blockHandler = "blockHandler"),其中blockHandler處理函數不執行 前置條件 //定義的資源 @GetMapping("/resource") @SentinelResource(value = ...
  • 電腦安全和數據隱私是現代應用程式設計中至關重要的方面。為了確保數據的機密性和完整性,常常需要使用加密和解密演算法。C++是一種廣泛使用的編程語言,提供了許多加密和解密演算法的實現。本文將介紹一些在C++中常用的加密與解密演算法,這其中包括Xor異或、BASE64、AES、MD5、SHA256、RSA等。 ...
  • 位運算 題目背景 題目由 daiyulong20120222 創作(me) 並由 QBW1117完善以及數據 。 題目描述 給定兩個數\(x,y\) ,在給定一個位運算符號 \(c\)。 請你列出 \(x,y\) 進行 \(c\) 位運算是的算數豎式式。 註: 豎式這麼列: 顯示出兩個數的完整二進位 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...