《經久不衰的Spring框架:SpringMVC 統括》


前言:經久不衰的Spring

       這幾年,前端技術更新換代速度之快,每一年“最火的前端技術”排行榜都會換一番場景,本當に信じかねる。是“只聞新人笑不見舊人哭”,還是“青山依舊在,幾度夕陽紅”,這些只有身處浪潮中才能慢慢體會。

       跑偏了,趕緊回歸正題。難道Java 相關技術沒有變革?那肯定不是,這邊說的只是Java 的企業級開發框架這塊。記得筆者剛入職那年,就在使用SSH三大框架,時至今日,公司采用的SSM框架,這其中經久不衰的就是Spring了。常見的SSH三大框架,就是Spring、Struts、Hibernate,到后來半ORM框架ibatis 出現了,接着改名Mybatis,若將MVC框架替換為SpringMVC,即湊成了SSM框架(筆者目前在用的各框架版本是Spring 4.2.6、Hibernate 4.3.1、Mybatis 3.2.8)。

      雖然是本人介紹Spring的第一篇文章,但這幾大框架我不用多加介紹了,網上文章多如牛毛,我再描述,那就有點老生常談的意味了。直接寫一些開發工作中,遇到相關卡殼問題和經驗總結,純屬記錄,畢竟Java當前吃飯的飯碗。

 

SpringMVC 簡介

  SpringMVC是一種基於Java的實現了 Web MVC 設計模式的請求驅動類型的輕量級Web框架,即使用了MVC架構模式的思想,將Web層進行職責解耦,基於請求驅動指的就是使用請求-響應模型,框架的目的就是幫助我們簡化開發。它和Struts一樣是一個MVC框架,它是Spring當中的一個子框架,和Spring無縫集成,和Struts2類似。

  SpringMVC的前端控制器是DispatcherServlet;應用控制器其實拆為處理器映射器(Handler Mapping)進行處理器管理和視圖解析器(View Resolver)進行視圖管理;頁面控制器/動作/處理器為Controller接口(僅包含ModelAndView handleRequest(request, response) 方法)的實現(也可以是任何的POJO類);支持本地化(Locale)解析、主題(Theme)解析及文件上傳等;提供了非常靈活的數據驗證、格式化和數據綁定機制;提供了強大的約定大於配置(慣例優先原則)的契約式編程支持。

  大概概述下 SpringMVC的步驟:

    l 步驟1—— 對Http請求進行初步處理,查找與之對應的Controller處理類(方法) ——HandlerMapping

    l 步驟2—— 調用相應的Controller處理類(方法)完成業務邏輯 ——HandlerAdapter

    l 步驟3—— 對Controller處理類(方法)調用時可能發生的異常進行處理 ——HandlerExceptionResolver

    l 步驟4—— 根據Controller處理類(方法)的調用結果,進行Http響應處理 ——ViewResolver

  使用SpringMVC框架好處:進行更簡潔的Web層的開發;天生與Spring框架集成(如IoC容器、AOP等);提供強大的約定大於配置的契約式編程支持;容易與其他視圖技術集成;對靜態資源的支持;支持Restful風格等等。

 

SpringMVC 與 Struts2

  這邊並不會去過多得對兩大框架進行對比,以免引發兩方陣營得爭論,只是簡單介紹一下Struts2框架,並繼續列舉認可SpringMVC的理由。

 

  什么是Struts2?

  Struts2是一個基於MVC設計模式的Web應用框架,它本質上相當於一個servlet,在MVC設計模式中,Struts2作為控制器(Controller)來建立模型與視圖的數據交互。Struts 2是Struts的下一代產品,是在 Struts 1和WebWork的技術基礎上進行了合並的全新的Struts 2框架。其全新的Struts 2的體系結構與Struts 1的體系結構差別巨大。Struts 2以WebWork為核心,采用攔截器的機制來處理用戶的請求,這樣的設計也使得業務邏輯控制器能夠與ServletAPI完全脫離開,所以Struts 2可以理解為WebWork的更新產品。雖然從Struts 1到Struts 2有着太大的變化,但是相對於WebWork,Struts 2的變化很小。 
 

  為什么是SpringMVC?

  1、相比Struts2,SpringMVC與Spring更加貼合,DispatcherServlet是前端控制器設計模式的實現,提供Spring Web MVC的集中訪問點,而且負責職責的分派,而且與Spring IoC容器無縫集成,從而可以獲得Spring的所有好處。
  
  2、設計原則更加明朗。這條重要的設計原則被寫在了spring官方的reference中SpringMVC章節的起始段: A key design principle in SpringWeb MVC and in Spring in general is the “Open for extension, closed for modification” principle. 並且重點很好地體現在SpringMVC的實現當中,可以擴展,但卻不能改變。我曾經擴展過Spring的IOC、AOP功能,這一點SpringMVC應該和Spring一脈相承。
  
  3、組件化的設計方案和特定的設計原則讓SpringMVC形散神聚,SpringMVC總是沿着一條固定的邏輯主線運行,卻擁有多種不同的行為模式。
 

SpringMVC 關鍵部分

  廢話不多說了,也該講一些實際一點的東西了。

  一、前端控制器 -- DispatcherServlet

  ※所有J2EE項目都是從web.xml啟動,閱讀或構建一個J2EE項目,都應該先找web.xml開始。

  ※任何MVC框架都需要一個入口,SpringMVC的入口是在web.xml文件中的核心分發DispatcherServlet;

  ※DispatcherServlet是前端控制器設計模式的實現,提供Spring Web MVC的集中訪問點,而且負責職責的分派,而且與Spring IoC容器無縫集成,從而可以獲得Spring的所有好處。DispatcherServlet默認使用WebApplicationContext作為上下文,Spring默認配置文件為/WEB-INF/[servlet名字]-servlet.xml;

<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*:mvc-config.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>SpringMVC</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

 

  二最簡注解映射配置

  筆者使用的是SpringMVC4.x,不用像SpringMVC3.0 時代,配置一大堆的HandlerMapping、HandlerAdapter、Converter。

  對,沒有錯,你僅僅需要配置一句話:<mvc:annotation-driven/>

  <mvc:annotation-driven/>相當於注冊了DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter兩個bean,配置一些messageconverter。即解決了@Controller注解的使用前提配置。

 

  三、靜態資源最優處理  

  如果你的DispatcherServlet攔截 *.do這樣的URL,就不存在訪問不到靜態資源的問題,但是要多書寫.do。

       如果你的DispatcherServlet攔截“/”,攔截了所有的請求,同時對*.js,*.jpg的訪問也就被攔截了。  

       當然,想要restful風格的話,就必須采用后者,那么就動手來解決一下靜態資源問題。

  方案一: 在Spring3.0.4以后版本提供了mvc:resources 

  mvc:resources 的使用方法:

<mvc:resources location="/images/" mapping="/images/**"/>

<mvc:resources location="/js/" mapping="/js/**"/>

<mvc:resources location="/css/" mapping="/css/**"/>

  說明:/images/**映射到 ResourceHttpRequestHandler進行處理,location指定靜態資源的位置.可以是web application根目錄下、jar包里面,這樣可以把靜態資源壓縮到jar包中。cache-period 可以使得靜態資源進行web cache 

 

  方案二 ,使用<mvc:default-servlet-handler/>

  說明:<mvc:default-servlet-handler/>  會把"/**" url,注冊到SimpleUrlHandlerMapping的urlMap中,把對靜態資源的訪問由HandlerMapping轉到 org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler 處理並返回。

  DefaultServletHttpRequestHandler使用就是各個Servlet容器自己的默認Servlet。

 

  方案三:激活Tomcat的defaultServlet來處理靜態文件
  web.xml中書寫代碼如下:
<servlet-mapping>
  <servlet-name>default</servlet-name>
  <url-pattern>*.jpg</url-pattern>
  <url-pattern>*.gif</url-pattern>
  <url-pattern>*.png</url-pattern>
  <url-pattern>*.js</url-pattern>
  <url-pattern>*.css</url-pattern>
  <url-pattern>*.html</url-pattern>
</servlet-mapping> 

  說明:本人采用這種方式,Tomcat直接處理靜態資源效率較高。缺點就是需要配置多個,每種文件配置一個,並且要寫在DispatcherServlet的前面,讓defaultServlet先攔截。

 

  四、視圖映射配置

  這點沒什么好說的,多種配置方式,直接上一種配置代碼: 

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/project/" p:suffix=".jsp" />

 

  五、文件上傳解析器

  SpringMVC實現多文件上傳的方式有兩種,一種是我們經常使用的以字節流的方式進行文件上傳,另外一種是使用SpringMVC包裝好的解析器進行上傳,這兩種方式對於實現多文件上傳效率上卻有着很大的差距,建議采用后者。

   部分配置如下:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
     <property name="defaultEncoding" value="utf-8"></property>   
     <property name="maxUploadSize" value="10485760000"></property>  
     <property name="maxInMemorySize" value="40960"></property>  
</bean>  

  說明:這邊不是文件上傳專欄,不詳細介紹。

 

  六、控制器掃描

  這部分其實應該歸納在Spring部分,但是SpringMVC也是基於Bean去操作的,需要掃描一下控制器Bean。

  配置代碼如下:

<context:component-scan base-package="com.demo"  use-default-filters="false">      
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />    
</context:component-scan>

 

  說明:這樣配置的意思是只掃描com.demo 包下@Controller 注解標注的類,use-default-filters屬性配置為false 是必須的。

 

 

編后語

  SpringMVC可以介紹的功能和內容無論從深度還是廣度上,都遠遠不止本文提到的這些內容,這些只不過是最基礎的部分。

  SpringMVC為Web開發提供了相當得便捷,但在用的過程中還是要理解它的實現原理和思路,再往深一層來說,它畢竟只是框架,它適合做什么、能夠做什么、怎么做,這些都應該由你自己做主,不能被框架左右。

  后續的博文會書寫Spring相關的一些技術點總結以及經驗之談,敬請關注。

  “風蕭蕭兮易水寒 壯士一去兮不復還”


免責聲明!

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



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