1. 程式人生 > >Spring入門(十二):Spring MVC使用講解

Spring入門(十二):Spring MVC使用講解

1. Spring MVC介紹

提到MVC,參與過Web應用程式開發的同學都很熟悉,它是展現層(也可以理解成直接展現給使用者的那一層)開發的一種架構模式,M全稱是Model,指的是資料模型,V全稱是View,指的是檢視頁面,如JSP、Thymeleaf等,C全稱是Controller,指的是控制器,用來處理使用者在客戶端(瀏覽器)發起的請求。

Spring MVC就是基於MVC模式實現,能夠幫你構建像Spring框架那樣靈活和鬆耦合的Web應用程式。

也就是說,Spring MVC是基於Spring的,它主要用來開發Web應用程式。

2. Spring MVC請求流程

在Web應用程式中,請求是必不可少的,每次請求由使用者(客戶端)發起,到使用者(客戶端)接收到響應結束,下圖展示了一個請求在Spring MVC中所經歷的每個流程:

接下來我們對圖中的每個流程做下講解:

  1. 請求離開瀏覽器時(圖中的①),會帶有使用者所請求內容的資訊,比如請求的URL和提交的表單資訊。
  2. 然後進入到請求的第一站,即Spring的DispatcherServlet,它的任務是將請求傳送給Spring MVC控制器。
  3. 因為在應用程式中會有多個控制器,因此DispatcherServlet會查詢一個或多個處理器對映(handler mapping),處理器對映會根據請求所攜帶的URL來確定應該將請求傳送給哪個控制器(圖中的②)。
  4. 確定好控制器後,DispatcherServlet會將請求傳送給確定好的控制器,然後等待控制器處理使用者提交的資訊,不過一般情況下,控制器本身幾乎不處理工作,而是將業務邏輯委託給一個或多個服務物件進行處理(圖中的③)。
  5. 控制器完成業務邏輯處理後,通常會產生一些模型(Model)資訊,這些資訊需要返回給使用者並在瀏覽器上顯示,為了更友好的展示這些資訊,比如以Html形式展示,我們需要將資訊傳送給一個檢視(View),比如JSP、Thymeleaf。
  6. 控制器所做的最後一件事就是將模型資料打包,並且標示出用於渲染輸出的檢視名,它會將請求連同模型和檢視名傳送回DispatcherServlet(圖中的④),不過控制器只會返回一個檢視的邏輯名稱,而不是返回具體的某個特定檢視,這個邏輯名稱將會用來查詢產生結果的真正檢視。DispatcherServlet會使用檢視解析器(view resolver)來將邏輯檢視名匹配為某個特定檢視(圖中的⑤),比如JSP或者Thymeleaf。
  7. 請求的最後一站是檢視的實現(圖中的⑥),在這裡檢視將使用模型資料渲染輸出,這個輸出會通過響應物件傳遞給使用者/客戶端(圖中的⑦)。

瞭解了Spring MVC的請求流程後,我們來接著瞭解下如何搭建和配置Spring MVC專案。

3. 搭建Spring MVC專案

我們仍然延用之前部落格中新建的spring-action專案,有興趣的同學可以看下本系列的前11篇部落格或者直接下載原始碼:https://github.com/zwwhnly/spring-action.git。

3.1 新增依賴

要想使用Spring MVC,首先我們需要在pom.xml中新增如下依賴:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.18.RELEASE</version>
</dependency>

<!-- 其他Web依賴 -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

因為後面要將專案部署到Tomcat,所以我們在pom.xml中配置下打包方式為war包:

<packaging>war</packaging>

<build>
    <plugins>
        <!--其他配置-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>3.2.3</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>
    </plugins>
</build>

3.2 新建演示頁面

在src/main/resources下新建views目錄,然後在此目錄下新建index.jsp頁面如下所示:

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<html>
<head>
    <title>Spring MVC</title>
</head>
<body>
    <pre>
        Welcome to Spring MVC world
    </pre>
</body>
</html>

這裡可能存在的問題是,右鍵新建JSP檔案時,沒有JSP檔案模板,就像下面這樣:

解決方案如下所示:

依次點選File--Project Structure,開啟Project Structure對話方塊,左側選中Modules,然後點選+號,選擇Web

此時再次右鍵新增JSP檔案,就會看到JSP檔案模板:

此時專案根目錄會生成1個web資料夾,可以將其刪除。

3.3 Spring MVC配置

新建配置類MyMvcConfig如下所示:

package chapter05.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

/**
 * Spring MVC配置
 */
@Configuration
@EnableWebMvc
@ComponentScan("chapter05")
public class MyMvcConfig {
    /**
     * 檢視解析器配置
     *
     * @return
     */
    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

        viewResolver.setPrefix("/WEB-INF/classes/views/");
        viewResolver.setSuffix(".jsp");
        viewResolver.setViewClass(JstlView.class);

        return viewResolver;
    }
}

注意事項:

1)該配置類使用了@EnableWebMvc註解來啟用Spring MVC,它會開啟一些預設配置。

2)該配置類配置了檢視解析器,這裡我們配置的是JSP的檢視解析器。

檢視解析器中,我們設定了字首和字尾,如果控制器中返回的邏輯檢視名稱是index,實際渲染時找的檢視就是/WEB-INF/classes/views/index.jsp,為什麼設定的字首是/WEB-INF/classes/views/而不是/src/main/resources/views/呢,那是因為專案編譯完執行時的目錄是/WEB-INF/classes/views/。

如果編譯完成該目錄下沒有jsp檔案,則需要在pom.xml中新增如下配置:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.jsp</include>
                <include>**/*.js</include>
            </includes>
        </resource>
    </resources>
</build>

3.4 Web配置

新建Web配置類WebInitializer如下所示:

package chapter05.config;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;

public class WebInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(MyMvcConfig.class);
        context.setServletContext(servletContext);

        Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(context));
        servlet.addMapping("/");
        servlet.setLoadOnStartup(1);
    }
}

這裡重點要關注的是,該類實現了介面WebApplicationInitializer並重寫了onStartup()方法,WebApplicationInitializer類是Spring提供用來配置Servlet 3.0+版本配置的介面,從而可以替代掉web.xml。

3.5 新建控制器

新建控制器HelloController如下所示:

package chapter05.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController {
    @RequestMapping("/index")
    public String hello() {
        // 這裡返回的邏輯檢視名
        return "index";
    }
}

上面程式碼中的@Controller註解宣告這是1個控制器,@RequestMapping("/index")用來配置URL對映,現在問題來了,我們如何檢視程式碼的執行效果呢?

這就涉及到了專案打包和專案部署,我們繼續往下看。

4. 專案部署到Tomcat中

4.1 打包(war包)

因為我們的專案是通過Maven管理的,在pom.xml中也配置了打包方式為war包和打包外掛,所以我們可以在IDEA的右側找到Maven資源管理器,然後如下圖所示,點選clean:

然後再點選package:

最後生成的war包如下所示:

這就是我們要部署到Tomcat中的war包。

4.2 Tomcat安裝及部署

既然要部署到Tomcat中,那麼就有2個問題需要解答:

  1. 什麼是Tomcat?
  2. Tomcat如何安裝?

先回答第1個問題,Tomcat是一個免費的開放原始碼的輕量級的Web應用伺服器,如果你接觸過.NET的Web開發,它就類似於IIS。

再回答第2個問題,可以參考如下步驟安裝Tomcat。

開啟Tomcat官網,找到你要下載的Tomcat版本,我這裡選擇的是Tomcat 8.5.45 Released版本:

然後選擇合適的版本下載,因為我的開發機器是Windows 64位作業系統,所以我選擇的是如下所示的版本:

下載完成後,將其解壓到你喜歡的目錄,我解壓到的目錄是E:\Tools\apache-tomcat-8.5.45-windows-x64\apache-tomcat-8.5.45,解壓完成後長如下這樣:

其中webapps就是網站要部署的目錄。

安裝完成後,考慮的問題就是如何啟動Tomcat?

第1種方法是雙擊bin目錄下的tomcat8.exe:

然後在瀏覽器輸入地址http://localhost:8080/,看到如下介面,代表Tomcat安裝部署成功。

使用這種方法的缺點就是,如果把tomcat8.exe開啟的視窗關閉了,Tomcat也就關閉了,非常不方便,因此建議使用第2種方法,將Tomcat安裝成一個後臺服務,讓其在後臺執行,操作方法如下所示:

依次開啟計算機--屬性--高階系統設定--高階--環境變數,新增系統變數:

變數名:CATALINA_HOME

變數值:E:\Tools\apache-tomcat-8.5.45-windows-x64\apache-tomcat-8.5.45(你將Tomcat解壓的目錄)

然後編輯系統變數Path,在其最後新增如下內容:

;%CATALINA_HOME%\lib;%CATALINA_HOME%\bin

然後以管理員身份開啟cmd視窗,切換到Tomcat的bin目錄,執行命令:service.bat install。

然後開啟Windows的服務列表,會看到一個Tomcat8的服務:

將服務修改成自動啟動並啟動該服務即可在後臺一直執行Tomcat伺服器。

如果你好奇新建的系統變數為什麼必須是CATALINA_HOME,那麼可以用記事本開啟bin目錄下的service.bat,看到如下內容你就明白了:

從上圖也可以看出,執行Tomcat需要依賴環境變數JAVA_HOME(配置JAVA SDK路徑),不過我之前已經配置過了,如下所示:

4.3 將war包部署到Tomcat中

將之前打包好的spring-action-1.0-SNAPSHOT.war複製到Tomcat的webapps目錄:

因為我們的Tomcat伺服器設定成了後臺執行,過一會該目錄就會生成1個和war包名相同的spring-action-1.0-SNAPSHOT資料夾,目錄結構如下所示:

我們的程式碼和JSP檢視檔案都在WEB-INF目錄下的classes資料夾下:

在瀏覽器中輸入地址http://localhost:8080/spring-action-1.0-SNAPSHOT/index,頁面展示如下所示:

5. 原始碼及參考

原始碼地址:https://github.com/zwwhnly/spring-action.git,歡迎下載。

Craig Walls 《Spring實戰(第4版)》

汪雲飛《Java EE開發的顛覆者:Spring Boot實戰》

【IntelliJ IDEA】使用idea解決新建jsp檔案而找不到jsp檔案模版的新建選項

Tomcat安裝及配置教程

Tomcat安裝及後臺執行的方法

6. 最後

歡迎掃碼關注微信公眾號:「申城異鄉人」,定期分享Java技術乾貨,讓我們一起進步。

相關推薦

Spring入門()Spring MVC使用講解

1. Spring MVC介紹 提到MVC,參與過Web應用程式開發的同學都很熟悉,它是展現層(也可以理解成直接展現給使用者的那一層)開發的一種架構模式,M全稱是Model,指的是資料模型,V全稱是View,指的是檢視頁面,如JSP、Thymeleaf等,C全稱是Controller,指的是控制器,用來處理使

Spring入門(四)Spring MVC控制器的2種測試方法

作為一名研發人員,不管你願不願意對自己的程式碼進行測試,都得承認測試對於研發質量保證的重要性,這也就是為什麼每個公司的技術部都需要質量控制部的原因,因為越早的發現程式碼的bug,成本越低,比如說,Dev環境發現bug的成本要低於QA環境,QA環境發現bug的成本要低於Prod環境,Prod環境發現bug的成本

Spring入門(一)Spring AOP使用進階

在上篇部落格中,我們瞭解了什麼是AOP以及在Spring中如何使用AOP,本篇部落格繼續深入講解下AOP的高階用法。 1. 宣告帶引數的切點 假設我們有一個介面CompactDisc和它的實現類BlankDisc: package chapter04.soundsystem; /** * 光碟 */ p

Spring Cloud 之呼叫鏈監控-Sleuth

1. 簡介 Spring Cloud Sleuth implements a distributed tracing solution for Spring Cloud. 微服務的呼叫鏈監控是解

Spring Security原始碼分析Spring Security OAuth2基於JWT實現單點登入

單點登入(英語:Single sign-on,縮寫為 SSO),又譯為單一簽入,一種對於許多相互關連,但是又是各自獨立的軟體系統,提供訪問控制的屬性。當擁有這項屬性時,當用戶登入時,就可以獲取所有

Spring Boot2()手摸手教你搭建Shiro安全框架

一、前言 SpringBoot+Shiro+Mybatis完成的。 之前看了一位小夥伴的Shiro教程,跟著做了,遇到蠻多坑的(´இ皿இ`) 修改整理了一下,成功跑起來了。可以通過postman進行測試 不多比比∠( ᐛ 」∠)_,直接上原始碼:https://github.com/niaobulashi/s

Spring入門(五)使用Spring JDBC操作資料庫

在本系列的之前部落格中,我們從沒有講解過操作資料庫的方法,但是在實際的工作中,幾乎所有的系統都離不開資料的持久化,所以掌握操作資料庫的使用方法就非常重要。 在Spring中,操作資料庫有很多種方法,我們可以使用JDBC、Hibernate、MyBatis或者其他的資料持久化框架,本篇部落格的重點是講解下在Sp

Spring Cloud (四)Spring Cloud 開源軟體都有哪些?

學習一門新的技術如果有優秀的開源專案,對初學者的學習將會是事半功倍,通過研究和學習優秀的開源專案,可以快速的瞭解此技術的相關應用場景和應用示例,參考優秀開源專案會降低將此技術引入到專案中的成本。為此抽了一些時間為大家尋找了一些非常優秀的 Spring Cloud 開源軟體供大家學習參考。 上次寫了一篇文章Sp

spring boot學習Spring Boot自動裝配分析與實戰

Web application conditions:@ConditionalOnWebApplication和@ConditionalOnNotWebApplication,當專案是web專案,或者不是web專案的條件註解 SpEL expression conditions:@Conditional

Spring Boot(一)Spring Boot中MongoDB的使用

Spring Boot(十一):Spring Boot中MongoDB的使用 mongodb是最早熱門非關係資料庫的之一,使用也比較普遍,一般會用做離線資料分析來使用,放到內網的居多。由於很多公司使用了雲服務,伺服器預設都開放了外網地址,導致前一陣子大批 MongoDB 因配置漏洞被攻擊,資料被刪,引起了人

Spring Boot(五)spring boot+jpa+thymeleaf增刪改查示例

app 配置文件 quest 重啟 fin nbu 生產 prot html Spring Boot(十五):spring boot+jpa+thymeleaf增刪改查示例 一、快速上手 1,配置文件 (1)pom包配置 pom包裏面添加jpa和thymeleaf的相關包引

《partner4java 講述Spring入門》之spring cache支援(spring3.1如何使用cache 快取)

(以下內容參照自官方文件;p4jorm下載地址http://blog.csdn.net/partner4java/article/details/8629578;cache demo下載地址http://download.csdn.net/detail/partner4ja

Spring入門()Spring AOP使用講解

1. 什麼是AOP? AOP是Aspect Oriented Programming的縮寫,意思是:面向切面程式設計,它是通過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術。 可以認為AOP是對OOP(Object Oriented Programming 面向物件程式設計)的補充,主要使用在日誌

springcloud()使用Spring Cloud Sleuth和Zipkin進行分散式鏈路跟蹤

Spring Cloud Sleuth 一般的,一個分散式服務跟蹤系統,主要有三部分:資料收集、資料儲存和資料展示。根據系統大小不同,每一部分的結構又有一定變化。譬如,對於大規模分散式系統,資料儲存可分為實時資料和全量資料兩部分,實時資料用於故障排查(troubleshooting),全量資料用於系統優化;資

第四Spring MVC框架之傳統增刪改查06

傳統CRUD 列表頁面: 新增頁面: 編輯頁面: 刪除操作: 匯入SpringMVC jar包 commons-logging-1.1.3.jar spring-aop-4.0.0.RELEASE.jar spring-beans-4.0.0.RELEAS

springcloud+springboot()使用Spring Cloud Sleuth和Zipkin進行分散式鏈路跟蹤

Spring Cloud Sleuth 一般的,一個分散式服務跟蹤系統,主要有三部分:資料收集、資料儲存和資料展示。根據系統大小不同,每一部分的結構又有一定變化。譬如,對於大規模分散式系統,資料儲存可分為實時資料和全量資料兩部分,實時資料用於故障排查(troubleshooting),全量資料用於系統優化

第四Spring MVC框架之多IOC容器整合15

多IOC容器整合 SSM整合方式 Spring、SpringMVC、MyBatis SpringMVC的核心Servlet會啟動一個IOC容器,而ContextLoaderListener也會啟動一個IOC容器。 web.xml <?xml version="1.

第四Spring MVC框架之資料校驗14

第十二章 資料校驗 在Web應用三層架構體系中,表述層負責接收瀏覽器提交的資料,業務邏輯層負責資料的處理。為了能夠讓業務邏輯層基於正確的資料進行處理,我們需要在表述層對資料進行檢查,將錯誤的資料隔絕在業務邏輯層之外。 1.校驗概述 JSR 303是Java為Bean資料合法性

第四Spring MVC框架之型別轉換13

SpringMVC將“把請求引數注入到POJO物件”這個操作稱為“資料繫結”。 資料型別的轉換和格式化就發生在資料繫結的過程中。 型別轉換和格式化是密不可分的兩個過程,很多帶格式的資料必須明確指定格式之後才可以進行型別轉換。 最典型的就是日期型別。 1.使用SpringMVC內建的型

第四Spring MVC框架之執行原理12

第十章 SpringMVC執行原理 找到一篇寫的不錯的部落格,大家可以看看 第一節 幾個重要元件 1.HandlerMapping 代表請求地址到handler之間的對映。 2.HandlerExecutionChain handler的執行鏈物件,由handler物件和所有ha