1. 程式人生 > 其它 >Spring MVC學習(一) Spring MVC基本介紹以及配置

Spring MVC學習(一) Spring MVC基本介紹以及配置

Spring MVC學習(一) Spring MVC基本介紹以及配置

  摘要:這篇筆記是對於Spring MVC的第一部分的學習中的整理,主要記錄了Spring MVC的基礎知識以及配置一個簡單的Spring MVC專案的方法

目錄

1.Java Web的發展歷史

1.1.Model I 和Model II

1.1.1.Model I開發模式

  Model I的開發模式是:JSP+JavaBean的模式,它的核心是Jsp頁面,在這個頁面中,Jsp負責整合頁面與業務邏輯,並且渲染頁面,其基本流程如下:

  我曾經在大學時代開發過這種結構的專案,上文提到的Jsp負責整合頁面與業務邏輯說白了就是前端渲染的html標籤資訊和Java程式碼混在了一起,在Jsp頁面中,我們會使用一種特殊的Java標籤將Java語言嵌入到前端頁面中,進而進行邏輯上的控制,這這一看非常方便,但是實際上這樣的設計模式導致一個Jsp頁面既負責檢視的展示,有負責業務流程的控制,耦合度極高,後期在維護的時候也必然是十分複雜。

1.1.2.Model II開發模式

  在Model II開發模式下,利用Jsp頁面、servlet和JavaBean元件分工協作共同完成系統的所有任務。其中Jsp頁面負責資料顯示邏輯任務,servlet負責程式的流程控制任務、JavaBean負責處理業務邏輯任務,其基本流程如下:

  這種模式的專案我也開發過,實際上就是加上一個Servlet部分,這個部分通常是用來進行前端和後端的資料互動,大部分與資料庫互動的程式碼都存在於JavaBean中,Servlet是呼叫這些方法的一個集合地,而前端通常是通過表單或者按鈕的形式(有時也可以用Ajax)向Servlet中進行請求的提交,這些請求就會觸發相應的JavaBean中的邏輯方法,記得大學時在學習完Model I之後,我們就主要在學習這種模式,直到幾個月前我還嘗試寫了幾個這個模式的專案。對於Model I來說,職責分工更加明確了,在Model I中抽取出了Servlet層,基本上體現了分層的思想,這種開發模式是非常符合當年,注意是當年的大型專案開發的,現在這種模式也已經過時了,一些小型專案或者是大學生畢業設計仍然會採用這種開發模式,但是大型的應用級別專案已經不使用這種開發模式了。

1.2.MVC模式

  MVC模式是符合當今開發思想的開發模式,典型者如Spring MVC,實際上Spring MVC是Spring的一個模組,專門做web開發,也就是專門做網站的一種開發模式,我們可以理解為Servlet的升級模式,在Spring MVC框架中,Controller替代Servlet擔負起控制器的職能。其中:

  M:指model(模型)層,指的是工程中的JavaBean,作用是資料處理,其中Java Bean也分為兩類,一類是實體類Bean,專門儲存業務資料用;一類為業務處理Bean,指的是Servlet或者Dao物件,專門處理業務邏輯和資料

  V:View(檢視)層,檢視層指專案當中的html或者Jsp等頁面,作用是與使用者進行互動,展示資料等。

  C:Controller(控制)層,指工程當中的Servlet,作用是接收請求和相應資料,需要注意的是,model層專門指實體類Bean,我們的一些實體類的模型都會放在model層中。

  MVC思想不是專門指某一個語言特有的設計模式,也不是web開發中所特有的思想,而是一種規範。MVC思想將一個應用分成三個基本部分:Model(模型)、View(檢視)和Controller(控制器),這三個部分以最少的耦合協同工作,進而提升了應用的可擴充套件性和可維護性。

2.Spring MVC的入門案例

 接下來讓我們搭建一個Spring MVC的專案,以此為學習Spring MVC的開端

1.工程建立

  首先如下圖所示,我們建立一個Maven專案,其中我們使用WEB模板:

  需要注意的是我們需要選擇下邊這個webapp,也就是這個:

  之後我們點選next,進行一些基本的配置,如設定專案名稱,組織名稱等,在學習階段,這些都可以隨心所欲他寫:

  設定Maven路徑:

  完成!

2.匯入座標

  在建立好專案之後,開發環境會為我們進行一個短暫的pom檔案生成,這時會自動生成一些座標與其他配置資訊,我們需要注意下面這條資訊:

  我們需要讓這個packaging標籤中的值為war,以保證我們打包出來的結果是一個war包,因為即將要被配置到伺服器框架中的專案的打包結果我們一般都會讓它是war包,伺服器框架們一般也是隻識別war包。之後我們將自己的座標依賴匯入到專案中,匯入我們需要的所有jar包,座標依賴如下:

<!--版本鎖定-->
<properties>
  <spring.version>5.0.2.RELEASE</spring.version>
</properties>

<dependencies>

  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
  </dependency>

  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${spring.version}</version>
  </dependency>

  <!--SpringMVC-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring.version}</version>
  </dependency>

  <!--servlet API-->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
  </dependency>

  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.0</version>
    <scope>provided</scope>
  </dependency>

  <!--日誌-->
  <dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
  </dependency>

  <dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring4</artifactId>
    <version>3.0.9.RELEASE</version>
  </dependency>

</dependencies>

  匯入成功:

3.修改XML文件

  我們將原有的xml文件用下邊的配置資訊完全替換:

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
   
 </web-app>

  之後我們開始配置DispatcheServlet,Spring MVC是基於原生的Servlet的,通過強大的前端控制器DispatcheServlet,對請求和相應進行統一處理。Spring MVC本質上就是一個Servlet,是對原生的Servlet進行了封裝,在以前我們瀏覽器的每一次請求都需要我們寫一個對應的Servlet,現在我們只需要將瀏覽器的請求和相應交給DispatchServlet進行統一處理,我們在web.xml配置檔案中配置核心控制器DispatcherServlet,配置資訊如下:

<!--在web.xml中配置Spring提供的過濾器類 -->
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <async-supported>true</async-supported>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<!--不攔截所有是html的頁面請求-->
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.html</url-pattern>
</servlet-mapping>

<!--配置前端控制器,對瀏覽器傳送的請求進行統一處理-->
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--載入springmvc.xml配置檔案的位置和名稱,配置的是Spring配置-->
    <init-param>
        <!--contextConfigLocation:上下文配置路徑,固定值-->
        <param-name>contextConfigLocation</param-name>
        <!--classpath:類路徑,值得是Java和resources資料夾-->
        <!--springmvc.xml:指的是配置檔案的名稱:需要配置springmvc.xml,在下面-->
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!--配置啟動載入-->
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!--開啟專案時開啟的頁面-->
<welcome-file-list>
    <welcome-file>/index.html</welcome-file>
</welcome-file-list>

  我們將這段資訊直接複製在web.xml內部,如圖所示:

  其中有一個位置會報錯:

  這是因為我們還需要一個Spring MVC配置檔案,Spring MVC專案怎麼能沒有Spring MVC配置檔案呢?不過現在讓我們稍安勿躁,我們先來簡單看看我們在web.xml中配置了些什麼。

3.1.過濾器

<!--在web.xml中配置Spring提供的過濾器類 -->
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <async-supported>true</async-supported>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

  這部分是我們的過濾器配置資訊,過濾器是專門過濾請求資訊的,同時還可以對請求資訊進行一系列的操作,這裡在filter-mapping標籤中定義了過濾的檔案型別,以及過濾器主體的名字,進而做一個對映。filter是過濾器的實體,在裡面規定了過濾器實體程式碼地址,是否支援非同步,編碼等資訊,這些規定會對整個專案中的提交申請以及資訊返回產生影響。

3.2.前端控制器

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>
<!--不攔截所有是html的頁面請求-->

  <!--配置前端控制器,對瀏覽器傳送的請求進行統一處理-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--載入springmvc.xml配置檔案的位置和名稱,配置的是Spring配置-->
    <init-param>
      <!--contextConfigLocation:上下文配置路徑,固定值-->
      <param-name>contextConfigLocation</param-name>
      <!--classpath:類路徑,值得是Java和resources資料夾-->
      <!--springmvc.xml:指的是配置檔案的名稱:需要配置springmvc.xml,在下面-->
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!--配置啟動載入-->
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  這個部分就是我們提到的最重要的前端控制器的部分。在這裡我們配置了兩個前端控制器的對映,其中一個是我們自己書寫的前端控制器,一個是預設的前端控制器,在預設的前端控制器對映中規定了攔截模式,這裡url-pattern標籤為*.html意味著不攔截所有的html頁面的請求,只要是請求html型別的檔案一律放行。

  在我們自己書寫的前端控制器中就精彩多了:

<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--載入springmvc.xml配置檔案的位置和名稱,配置的是Spring配置-->
    <init-param>
      <!--contextConfigLocation:上下文配置路徑,固定值-->
      <param-name>contextConfigLocation</param-name>
      <!--classpath:類路徑,值得是Java和resources資料夾-->
      <!--springmvc.xml:指的是配置檔案的名稱:需要配置springmvc.xml,在下面-->
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!--配置啟動載入-->
    <load-on-startup>1</load-on-startup>
  </servlet>

  首先載入了前端控制器的實體類,然後我們在裡邊加入了springmvc.xml的對映資訊,以便於專案載入springmvc.xml中的資訊,load-on-startup是啟動載入模式。我們在自己書寫的前端控制器對映中還限制了請求的型別:

<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  servlet-mapping標籤中的url-pattern為"/",意思為不攔截任何資訊,非常寬泛的一個攔截。

3.3.重要的url-pattern標籤

  我發現很多部分中都存在url-pattern這個標籤,這個標籤是幹什麼用的呢?這個標籤實際上就是進行請求攔截用的,它會對符合其內部格式的檔案請求放行,否則將攔截,這裡有一個對照說明表:

精切匹配 /具體的名稱 只有url路徑是具體的名稱時才會被通過並觸發Servlet
字尾匹配 *.XXX 只要是字尾為XXX的請求就會被通過
萬用字元匹配 /* 匹配所用請求(在訪問的時候,“/”後邊些什麼都能匹配到當前的資源,能夠訪問到伺服器上的所有資源)
萬用字元匹配 / 匹配所有請求,能夠訪問到伺服器上的所有資源,但是不包括.jsp檔案

4.配置springmvc.xml檔案

  專案中不自帶這個檔案,所有我們首先要自己建立一個,在此之前,我們要現在專案的main目錄下建立兩個重要的目錄,分別是java源程式目錄和resource資源目錄:

  然後我們在resource目錄下建立springmvc.xml檔案:

  然後我們就建立好了:

  我們把下面的配置資訊複製到springmvc.xml中去:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--配置spring建立容器時要掃描的包-->
    <context:component-scan base-package="com.spruce"></context:component-scan>

    <!--處理對映器-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

    <!--處理器介面卡-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

    <!--配置檢視解析器-->
    <bean id="viewResolver" class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
        <property name="order" value="1"/>
        <property name="characterEncoding" value="UTF-8"/>
        <property name="templateEngine" ref="templateEngine"/>
    </bean>
    <!-- templateEngine -->
    <bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
        <property name="templateResolver" ref="templateResolver"/>
    </bean>
    <bean id="templateResolver" class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
        <property name="prefix" value="/html/" />
        <property name="suffix" value=".html" />
        <property name="templateMode" value="HTML5"/>
    </bean>
    
    <!-- 配置spring開啟註解mvc的支援  預設就是開啟的 ,要想讓其他元件(不包含對映器、介面卡、處理器)生效就必須需要配置了-->
    <mvc:annotation-driven></mvc:annotation-driven>
</beans>

  關於這個配置資訊的結構我已經在之前的一篇筆記中記載過了,這裡暫且不再深究,以後有時間我們慢慢品讀,在此附上跳轉連結,點選跳轉。唯一一點需要注意的就是這個標籤:<mvc:annotation-driven></mvc:annotation-driven>,如果引用地址寫的不具體,我們在書寫這個標籤的時候會有多個選擇,也就是可以從不同的地址中書寫同樣的這一個標籤,這裡我們注意,我們選擇那個地址的末尾是mvc的,否則會報錯。

5.建立模擬操作

5.1.建立index.html

  在上面的配置資訊中我們把歡迎頁面設定成為了index.html,在這個專案中只有一個index.jsp,因為jsp落後了我們暫且不學它了,所有把它替換成下面的index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>歡迎來到米奇妙妙屋</title>
</head>
<body>
	<h3>入門</h3><a href="/SpringMVCStudy/hello" >入門程式</a>
</body>
</html>

5.2.建立hello這個servelt

  我們開始書寫hello這個servlet,我們需要在Java中建立com.spruce包,然後再其下邊建立一個controller包,然後在其下面建立這個servlet,其名字為HelloController:

package com.spruce.controller;

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

@Controller
public class HelloController {
    /**
     * 處理超連結傳送出來的請求
     * @param model
     * @return
     */
    @RequestMapping(path = "/hello")
    public String sayHello(Model model){

        System.out.println("入門方法執行了2...");
        // 向模型中新增屬性msg與值,可以在html頁面中取出並渲染
        model.addAttribute("msg","hello,SpringMVC");
        // 配置了檢視解析器後,寫法
        return "suc";

    }
}

5.3.建立suc.html

  這是我們的跳轉目的地,程式碼如下,我們將其建立在webapp下的html目錄中,因為剛才的配置檔案中對其的路徑檢索就是html目錄下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">

    <title>成功</title>
</head>
<body>
<h1>Hello <b th:text="${msg}"></b></h1>
</body>
<script>
</script>
</html>

6.配置tomcat並測試

  現在讓我們配置一個tomcat然後對這個專案進行測試吧,下面是配置tomcat的過程:

6.1.點選新增配置

6.2.新增tomcat配置

6.3.設定配置資訊

  在該頁面下我們可以設定自己的tomcat路徑,然後修改其訪問路徑:

  然後點選ok就完成了,完成後專案中會出現這樣的東西:

6.4.測試

  點選執行按鈕,就會自動觸發瀏覽器並進入下面的頁面:

  點選這個名為入門程式的按鈕,就可以進入如下頁面:

  能夠進入如下頁面則視為成功。