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安裝及后台運行的方法

原創不易,如果覺得文章能學到東西的話,歡迎點個贊、評個論、關個注,這是我堅持寫作的最大動力。

如果有興趣,歡迎添加我的微信:zwwhnly,等你來聊技術、職場、工作等話題(PS:我是一名奮斗在上海的程序員)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM