SpringMVC(day1搭建SpringWebMvc項目)

MVC和webMVC的區別javascript

Model(模型)
數據模型,提供要展現的數據,所以包含數據和行爲,行爲是用來處理這些數據的。不過如今通常都分離開來:Value Object(數據) 和 服務層(行爲)。也就是數據由實體類或者javabean來提供,行爲由service層來提供.

View(視圖)
負責進行模型的展現,通常就是咱們見到的用戶界面,客戶想看到的東西。css

Controller(控制器)
接收用戶請求,委託給模型進行處理,處理完畢後把返回的模型數據交給給視圖。也就是說控制器在中間起到一個調度的做用。html

在標準的MVC中,模型能主動推數據給視圖進行更新(能夠採用觀察者設計模式實現,在模型上註冊視圖,當模型更新時自動更新視圖),但在Web開發中模型是沒法主動推給視圖,即沒法主動更新用戶界面,由於在Web的訪問是請求-響應的模式。必須由客戶端主動發出請求後,服務器才能把數據返回。前端

MVC和三層架構的區別java

MVC是屬於三層架構中的表示層的一個框架,M至關於javabean,V至關於jsp,而C就至關於Servletweb

SpringWebMVC概述(SpringMVC)spring

SpringWebMVC簡稱SpringMVCexpress

SpringMVC就是Spring框架提供的一個模塊,經過實現MVC模式來很好地將數據、業務與展示進行分離,SpringMVC框架的目的是要簡化咱們平常的Web開發。設計模式

SpringMVC框架跟其餘的WebMVC框架同樣,都是*請求驅動*,而且設計圍繞一個可以分發請求到控制器以及提供其餘加快web應用開發功能的核心Servlet(叫作DispatcherServlet,即前端控制器)。Spring的DispatcherServlet實現比其餘框架中還要多的功能。它和spring的ioc容器徹底整合,而且容許使用spring中其餘的全部功能。tomcat

SpringMVC框架設計的一個核心的原則就是"開閉原則",對擴展開放,對修改關閉.因此SpringMVC框架中不少方法都是final的,不容許用戶隨意覆蓋,可是卻提供給用戶不少可擴展的機制(springmvc提供了不少接口)。SpringMVC目前已經成爲很是流行的web應用的框架。

經過這張圖咱們來認識SpringMVC框架的核心組件

1.DispatcherServlet這是Spring提供的一個核心Servlet能夠將請求分發給不一樣的Handler進行處理,用法很簡單啊,在web.xml文件中配置一下就能夠了

例如:

          <servlet>
            <servlet-name>SpringMVC</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
          </servlet>
          <servlet-mapping>
            <servlet-name>SpringMVC</servlet-name>
            <url-pattern>*.action</url-pattern>
          </servlet-mapping>

 

這個類是與指定要讀取的配置文件有關的,類中的許多方法取決於你的配置,在配置文件中配置的HandlerMapping: 處理器映射器,HandlerAdaptor:處理器適配器是與這個類的初始化有關的

                                ⬇

2.HandlerMapping: 處理器映射器。DispatcherServlet接收到客戶端請求的URL以後,根據必定的匹配規則,再把請求轉發給對應的Handler,這個匹配規則由HandlerMapping決定。

也就是說轉發請求給哪一個handler處理是取決於HandlerMapping的映射關係的,通常來講咱們使用默認的根據url和處理器名字進行匹配<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">

                                   ⬇

3.HandlerAdaptor:處理器適配器。處理器適配器用來適配每個要執行的Handler對象。經過HandlerAdapter能夠支持任意的類做爲處理器,通常來講咱們使用默認適配器,能夠處理的是實現了Controller接口的控制器對象【實現

Controller接口的控制器】<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>這個類中定義了方法,能夠分析處理器映射器映射到的handler是不是Controller的實現類,能夠調用Controller的實現類中的

handleRequest方法。這個適配器能夠仿照默認的本身寫一個,能夠實現讓任意一個類來作處理器。如下是默認處理器適配器部分源碼

public class SimpleControllerHandlerAdapter implements HandlerAdapter {   /*先判斷handler是否是一個處理器*/   @Override   public boolean supports(Object handler) {     return (handler instanceof Controller);   }   @Override   public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {     /*指定調用handler中的handleRequest方法*/

    return ((Controller) handler).handleRequest(request, response);   } }

 

4.根據源碼咱們能夠發現,其實是HandlerAdaptor幫咱們調用了Handler中的方法Controller/Headler: 控制器/處理器。開發人員自定義,用來處理用戶請求的,而且處理完成以後返回給用戶指定視圖的對象。

例如一個簡單的Handler:

//控制器、處理器
//用來接收前端控制器發送過來的請求,而且處理請求返回模型視圖對象。
public class HelloController implements Controller{

    @Override
    public ModelAndView handleRequest(HttpServletRequest request, 
            HttpServletResponse response) throws Exception {
        //操做和原來servlet是同樣的
        
        //模型和視圖對象
        ModelAndView mv = new ModelAndView();
        
        //往模型對象中存放值
        mv.addObject("name", "tom");
        
        //指定跳轉頁面的邏輯視圖名
        //mv.setViewName("/WEB-INF/jsp/hello.jsp");
        mv.setViewName("hello");
        
        return mv;
    }
}

 

        ⬇

5.ViewResolver:視圖解析器。Handler返回的是邏輯視圖名,須要有一個解析器可以將邏輯視圖名轉換成實際的物理視圖。並且Spring的可擴展性決定了視圖能夠由不少種,因此須要不一樣的視圖解析器,解析不一樣的視圖。可是通常由jsp充當視圖的狀況居多通常來講仍是使用默認的居多

 

   <!-- 將邏輯視圖名變爲要訪問的資源地址 -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 配置jstl相關內容 -->
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <!-- 給邏輯視圖名加前綴 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- 給邏輯視圖名加後綴 -->
        <property name="suffix" value=".jsp" />
    </bean>

        ⬇

SpringMVC框架提供一個核心的Servlet對象(DispatcherServlet,前端控制器)來對服務器接收到的請求進行解析,當這個請求被DispatcherServlet獲取到以後,DispatherServlet須要根據HandlerMapping對象的映射關係,將這個請求轉交給真正可以處理客戶端請求的Controller控制器(咱們要寫的就是這個東西,至關於以前的servlet)來處理。Controller處理完成後返回ModelAndView對象,也就是模型和視圖的結合體。ViewResolver視圖解析器根據ModelAndView中的邏輯視圖名找到真正的物理視圖,同時使用ModelAndView中模型裏面的數據對視圖進行渲染。最後把準備好的視圖展示給用戶

SpringMVC框架在項目中的搭建

第一步:構建Web項目
第二步:導入所需jar包
第三步:配置前端控制器DispatcherServlet
第四步:編寫Controller控制器(也稱爲Handler處理器)
第五步:配置處理器映射器(可省去,有默認配置)
第六步:配置處理器適配器(可省去,有默認配置)
第七步:配置視圖解析器(可省去,有默認配置,可是前綴和後綴都爲"")
第八步:配置控制器/處理器

 

1)構建Web項目
在本身Eclipse中建立一個動態web項目(DynamicWebProject),注意JDK版本和項目版本的選擇

2)導入所需的jar包
在lib目錄下放入以下jar包,這是初始jar包,根據後續需求會陸續加入jar包
commons-logging-1.2.jar
spring-beans-4.3.7.RELEASE.jar
spring-context-4.3.7.RELEASE.jar
spring-core-4.3.7.RELEASE.jar
spring-expression-4.3.7.RELEASE.jar
spring-web-4.3.7.RELEASE.jar
spring-webmvc-4.3.7.RELEASE.jar

3)配置前端控制器DispatcherServlet以及須要讀取的xml配置文件

SpringMVC的前端控制器就是一個Servlet對象,繼承自HttpServlet,因此須要在web.xml文件中配置。

SpringMVC是Spring提供的一個模塊,Spring全部的模塊都是基於Spring IOC功能的。因此SpringMVC的DispatcherServlet對象在初始化以前也會去實例化Spring的容器對象(ApplicationContext),那麼就須要讀取Spring的配置文件。

默認SpringMVC會在你web應用的WEB-INF目錄下查找一個名字爲[servlet-name]-servlet.xml文件,而且建立在這個文件中定義的bean對象。

若是你提供的spring配置文件的名字或者位置和默認的不一樣,那麼須要在配置servlet時同時指定配置文件的位置。

例如:

<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>

 

如上配置,框架會自動去當前應用的WEB-INF目錄下查找名字爲SpringMVC-servlet.xml文件(默認前綴和<servlet-name>標籤中的值一致)。
也能夠本身指定配置文件的名字和位置:

<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-web-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>

 

注意:
配置文件在WEB-INF下:
<param-value>/WEB-INF/spring-web-mvc.xml</param-value>
配置文件在classpath下:
<param-value>classpath:spring-web-mvc.xml</param-value>

注意:
<url-pattern>*.action</url-pattern>
也能夠配置成
<url-pattern>/</url-pattern>

注意:這裏是/ 不是/*,後面會說明它們之間的區別

4)編寫Controller控制器(headler)而且在xml中配置

<!-- 配置Controller處理器 -->
<bean name="/hello.action"
class="com.briup.controller.HelloController"></bean>

 

5)配置映射器(可省去,有默認配置)

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

6)配置適配器(可省去,有默認配置)

想要正確運行自定義處理器,須要配置處理器適配器,在spring的配置文件中(就是本例中的SpringMVC-servlet.xml),進行以下配置:

<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

SimpleControllerHandlerAdapter:表示全部實現了org.springframework.web.servlet.mvc.Controller接口的Bean能夠做爲SpringMVC中的處理器。若是須要其餘類型的處理器能夠經過實現HadlerAdapter來解決。

 7)配置視圖解析器(可省去,有默認配置,可是前綴和後綴都爲"")

當處理器執行完成後,返回給spring容器一個ModelAndView對象,這個對象須要可以被解析成與之相對應的視圖,而且使用返回的Model數據對視圖進行渲染。

<bean 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>

 

若是配置設置爲如上操做,那麼在自定義的Handler中返回的邏輯視圖的名字不能有後綴.jsp,而且具體頁面必定放在/WEB-INF目錄下。

InternalResourceViewResolver:用於支持Servlet、JSP視圖解析;
viewClass:JstlView表示JSP模板頁面須要使用JSTL標籤庫,classpath中必須包含jstl的相關jar包;
prefix和suffix:視圖頁面的前綴和後綴(前綴+邏輯視圖名+後綴),好比傳進來的邏輯視圖名爲hello,則該該jsp視圖頁面應該存放在"WEB-INF/jsp/hello.jsp"

注意:放在WEB-INF下的頁面,只能經過內部跳轉的方式訪問到,由於客戶端訪問不到WEB-INF目錄,並且服務器端能夠訪問到WEB-INF目錄
注意:須要引入jstl相關jar包
注意:頁面中的路徑問題
相對路徑
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<base href="<%=basePath%>" />

8)配置處理器
把編寫好的handler/controller在spring中進配置,讓其接受Spring IoC容器管理
<bean name="/hello.action" class="com.briup.web.controller.HelloWorldController"/>

如今咱們來處理DispatcherServlet中的映射路徑問題

 

<servlet>
  <servlet-name>SpringMVC</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>SpringMVC</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

 

1)攔截全部請求 /
<url-pattern>/</url-pattern>
此處須要特別強調的是,配置中使用的是/,而不是/*,若是使用/*,那麼請求時能夠經過DispatcherServlet轉發到相應的Controller中,可是Controller返回的時候,如返回的jsp還會再次被攔截,這樣致使404錯誤,即訪問不到jsp。

攔截/,例如:/user/add
未來能夠實現REST風格的訪問
弊端:會致使靜態文件(jpg,js,css)被攔截後不能正常顯示。

攔截/*,請求能夠走到Controller中,但跳轉到jsp時再次被攔截,不能訪問到jsp,能夠說這是錯誤的配置。

2)自定義攔截請求的後綴名
攔截*.do、*.html、*.action, 例如/user/add.do
這是最傳統的方式,最簡單也最實用。不會致使靜態文件(jpg,js,css)被攔截。

弊端:
Controller的後綴只能固定成某一個
未來不便於實現REST風格的訪問

3)靜態資源的訪問,如jpg,js,css
若是DispatcherServlet攔截"*.do"這樣的有後綴的URL,就不存在訪問不到靜態資源的問題。
  若是DispatcherServlet攔截"/",爲了實現REST風格,攔截了全部的請求,那麼同時對*.js,*.jpg等靜態文件的訪問也就被攔截了。
例如:
<link href="static/css/hello.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="static/js/hello.js"></script>
<img alt="none" src="static/images/logo.png">

解決方式一:利用Tomcat的defaultServlet來處理靜態文件

<servlet-mapping>
  <servlet-name>default</servlet-name>
  <url-pattern>*.jpg</url-pattern>
</servlet-mapping>

<servlet-mapping>
  <servlet-name>default</servlet-name>
  <url-pattern>*.js</url-pattern>
</servlet-mapping>

<servlet-mapping>
  <servlet-name>default</servlet-name>
  <url-pattern>*.css</url-pattern>
</servlet-mapping>

 

或者:

<servlet-mapping>
  <servlet-name>default</servlet-name>
  <url-pattern>*.css</url-pattern>
  <url-pattern>*.js</url-pattern>
  <url-pattern>*.png</url-pattern>
</servlet-mapping>

 

特色:1.要配置多個,每種文件配置一個。
   2.要寫在DispatcherServlet的前面(和tomcat版本有關),讓defaultServlet先攔截請求, 這樣請求就不會進入Spring了
   3. 高性能。

解決方式二: 使用<mvc:resources>標籤,例如:
<mvc:resources mapping="/images/**" location="/images/"/>
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/>

mapping: 映射
兩個*,表示映射指定路徑下全部的URL,包括子路徑
location:本地資源路徑

這樣若是有訪問/images或者/js或者/css路徑下面的資源的時候,spring就不會攔截了

解決方式三: 使用<mvc:default-servlet-handler/>標籤
在spring配置文件中加入此標籤配置便可

最後是一個spring提供的編碼過濾器(這是Springmvc提供的過濾器)
查看這個過濾器類源碼即可知這裏所傳的倆個參數的做用

<filter>
  <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
相關文章
相關標籤/搜索