SpringMVC 學(xué)習(xí)(一)簡(jiǎn)介、運(yùn)行原理

用戶協(xié)議通過(guò)http協(xié)議到達(dá)前端控制器,前端控制器判斷該有誰(shuí)來(lái)處理,將請(qǐng)求帶給controller(控制器),控制器了解業(yè)務(wù)處理邏輯細(xì)節(jié)(負(fù)責(zé)數(shù)據(jù)抽取),將業(yè)務(wù)邏輯生成數(shù)據(jù)返回給前端控制器,前端控制器再將業(yè)務(wù)邏輯分發(fā)給業(yè)務(wù)視圖,由業(yè)務(wù)視圖呈獻(xiàn)業(yè)務(wù)頁(yè)面,再將業(yè)務(wù)頁(yè)面返還給前端控制器,最終返還給客戶端。

MVC本質(zhì):MVC的核心思想是業(yè)務(wù)數(shù)據(jù)的抽取同業(yè)務(wù)數(shù)據(jù)呈現(xiàn)相分離。

SpringMVC框架介紹

Spring 框架提供了構(gòu)建 Web 應(yīng)用程序的全功能 MVC 模塊。使用 Spring 可插入的 MVC 架構(gòu),可以選擇是使用內(nèi)置的 Spring Web 框架還是 Struts 這樣的 Web 框架。通過(guò)策略接口,Spring 框架是高度可配置的,而且包含多種視圖技術(shù),例如 JavaServer Pages(JSP)技術(shù)、Velocity、Tiles、iText 和 POI。Spring MVC 框架并不知道使用的視圖,所以不會(huì)強(qiáng)迫您只使用 JSP 技術(shù)。
Spring MVC 分離了控制器、模型對(duì)象、分派器以及處理程序?qū)ο蟮慕巧@種分離讓它們更容易進(jìn)行定制

Spring的MVC框架主要由DispatcherServlet、處理器映射、處理器(控制器)、視圖解析器、視圖組成。

SpringMVC就是通過(guò)DispatcherServlet將一堆組件串聯(lián)起來(lái)的Web框架。

SpringMVC的原理

SpringMVC接口解釋

DispatcherServlet接口:
Spring提供的前端控制器,所有的請(qǐng)求都有經(jīng)過(guò)它來(lái)統(tǒng)一分發(fā)。在DispatcherServlet將請(qǐng)求分發(fā)給Spring Controller之前,需要借助于Spring提供的HandlerMapping定位到具體的Controller。

HandlerAdapter接口:
HandlerAdapter相當(dāng)于controller,DispatcherServelet調(diào)用各種HandlerAdapter來(lái)實(shí)現(xiàn)任務(wù)分發(fā)給相關(guān)的業(yè)務(wù)邏輯。

HandlerInterceptor:
HandlerInterceptor是一個(gè)接口,可以用來(lái)在Handler調(diào)用之前、之后,以及view呈現(xiàn)后可以做很多事情。

HandlerMapping接口:
HandlerMapping是負(fù)責(zé)確定DispatcherServelet與controller之間映射的類(lèi),告訴DispatcherServelet,在請(qǐng)求到來(lái)后,由哪個(gè)controller來(lái)響應(yīng)這個(gè)請(qǐng)求。

Controller接口:
Controller將處理用戶請(qǐng)求,這和Struts Action扮演的角色是一致的。一旦Controller處理完用戶請(qǐng)求,則返回ModelAndView對(duì)象給DispatcherServlet前端控制器,ModelAndView中包含了模型(Model)和視圖(View)。

ViewResolver接口:
Spring提供的視圖解析器(ViewResolver)在Web應(yīng)用中查找View對(duì)象,從而將相應(yīng)結(jié)果渲染給客戶。

SpringMVC運(yùn)行原理

  1. 客戶端請(qǐng)求提交到DispatcherServlet

  2. 由DispatcherServlet控制器查詢(xún)一個(gè)或多個(gè)HandlerMapping,找到處理請(qǐng)求的Controller

  3. DispatcherServlet將請(qǐng)求提交到Controller

  4. Controller調(diào)用業(yè)務(wù)邏輯處理后,返回ModelAndView

  5. DispatcherServlet查詢(xún)一個(gè)或多個(gè)ViewResoler視圖解析器,找到ModelAndView指定的視圖

  6. 視圖負(fù)責(zé)將結(jié)果顯示到客戶端


DispatcherServlet是整個(gè)Spring MVC的核心。它負(fù)責(zé)接收HTTP請(qǐng)求組織協(xié)調(diào)Spring MVC的各個(gè)組成部分。其主要工作有以下三項(xiàng):

  • 截獲符合特定格式的URL請(qǐng)求。
  • 初始化DispatcherServlet上下文對(duì)應(yīng)的WebApplicationContext,并將其與業(yè)務(wù)層、持久化層的WebApplicationContext建立關(guān)聯(lián)。
  • 初始化Spring MVC的各個(gè)組成組件,并裝配到DispatcherServlet中。

配置SpringMVC需要的配置文件

DispatcherServlet是整個(gè)Spring MVC的核心,SpringMVC所有的請(qǐng)求都會(huì)通過(guò)這個(gè)前端控制器。
我們可以根據(jù)需要配置一個(gè)或多個(gè)ApplicationContext,常見(jiàn)的做法是配置一個(gè)根ApplicationContext和一個(gè)前端ApplicationContext。前端ApplicationContext定義網(wǎng)絡(luò)相關(guān)的配置,根ApplicationContext配置數(shù)據(jù)庫(kù)等網(wǎng)絡(luò)無(wú)關(guān)的組件。這樣的話就需要web.xml寫(xiě)成類(lèi)似這樣的。
它配置的地方是在web.xml里面:

  <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <!-- 配置全局的applicationContext -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <!-- 配置spring的核心servlet -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <!--如果只需要一個(gè)ApplicationContext,值留空-->
            <param-value>classpath:spring/dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!-- 該監(jiān)聽(tīng)器將在web容器啟動(dòng)時(shí)激活spring -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- 處理有JavaBean、Introspector的使用而引起的緩沖泄露,建議配置此監(jiān)聽(tīng)器 -->
    <listener>
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
    </listener>
    <!-- 編碼過(guò)濾器 -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- session的有效時(shí)間 -->
    <session-config>
        <session-timeout>60</session-timeout>
    </session-config>
</web-app>

配置的時(shí)候還指明了contextConfigLocation,這樣就會(huì)去加載這個(gè)applicationContext.xml了。
在上面的配置中,我們創(chuàng)建了兩個(gè)ApplicationContext,一個(gè)是全局的,另一個(gè)是前端控制器dispatcher-servlet使用的。
這里的ApplicationContext其實(shí)是一個(gè)WebApplicationContext,它可以配置一些網(wǎng)絡(luò)相關(guān)的組件,例如視圖解析器、異常解析器、主題解析器等等。

由于SpringMVC啟動(dòng)的時(shí)候會(huì)讀取WEB-INF/applicationContext.xml
所以要在WEB-INF下創(chuàng)建一個(gè)空的applicationContext。xml

配置視圖解析器

spatcherServlet控制器查詢(xún)一個(gè)或多個(gè)HandlerMapping,找到處理請(qǐng)求的Controller。這里其實(shí)是通過(guò)在dispatcher-servlet.xml配置了掃描路徑以及開(kāi)啟了注解驅(qū)動(dòng)來(lái)實(shí)現(xiàn)的。

dispatcher-servlet.xml中的配置:

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

    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- 指定讓Spring的DispatcherServlet作為默認(rèn)Servlet,這樣我們就可以讓Spring處理根路徑/的請(qǐng)求了。
    如果不加這個(gè),那么根路徑的請(qǐng)求默認(rèn)會(huì)由服務(wù)器來(lái)處理。 -->
    <mvc:default-servlet-handler/>
    <!-- 啟用MVC的注解支持。如果不添加這個(gè),那么我們就需要在XML文件中為每個(gè)控制器寫(xiě)一個(gè)Bean配置 -->
    <mvc:annotation-driven/>
    <!-- 用來(lái)掃描指定的路徑下的包,告訴Spring從哪里搜索注解來(lái)加載組件用的 -->
    <context:component-scan base-package="com.meng"/>
</beans>

context:component-scan說(shuō)明了要掃描com.meng.demo這個(gè)包下所有的類(lèi)。
這里要注意一下,在開(kāi)發(fā)中有用到注解的類(lèi)一定都要在這個(gè)demo包下,不然就會(huì)拋異常的。

加載了掃描路徑后,還要開(kāi)啟注解驅(qū)動(dòng),這樣才能認(rèn)到代碼中使用到的注解,,比如@Controller這個(gè)注解。

<mvc:annotation-driven />

ViewResoler視圖解析器對(duì)應(yīng)配置里面的

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
          <!--  前綴 -->
        <property name="prefix" value="/WEB-INF/pages/"/>
      <!--  后綴 -->
        <property name="suffix" value=".jsp"/>
</bean>

這樣,當(dāng)controller中方法返回的是

return "index";

的時(shí)候,實(shí)際是指向了/WEB-INF/pages/index.jsp這個(gè)頁(yè)面。

上面的配置可以使用mvc命名空間簡(jiǎn)化。我們可以使用如下的配置替代上面的視圖解析器配置。

<mvc:view-resolvers>
    <mvc:jsp view-class="org.springframework.web.servlet.view.JstlView"
             prefix="/WEB-INF/jsp/"
             suffix=".jsp"/>
</mvc:view-resolvers>

創(chuàng)建Controller

package com.meng;

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

@Controller
@RequestMapping("/mvc")
public class MainController {
    @RequestMapping(value = "/index")
    public String index(Model model) {
        model.addAttribute("name", "李帆");
        return "index";
    }
}

啟動(dòng)服務(wù)器訪問(wèn) http://localhost:8080/mvc/index

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容