一棉圈、SpringMVC簡介
1.1 SpringMVC為什么出現(xiàn)
很多應(yīng)用程序的問題在于處理業(yè)務(wù)數(shù)據(jù)和顯示業(yè)務(wù)數(shù)據(jù)的視圖的對象之間存在緊密耦合堆缘。通常,更新業(yè)務(wù)對象的命令都是從視圖本身發(fā)起的,使視圖對任何業(yè)務(wù)對象更改都有高度敏感性漱凝。而且,當(dāng)多個(gè)視圖依賴于同一個(gè)業(yè)務(wù)對象時(shí)是沒有靈活性的诸迟。
Spring Web MVC是一種基于Java的實(shí)現(xiàn)了Web MVC設(shè)計(jì)模式的請求驅(qū)動(dòng)類型的輕量級Web框架茸炒,即使用了MVC架構(gòu)模式的思想愕乎,將web層進(jìn)行職責(zé)解耦,基于請求驅(qū)動(dòng)指的就是使用請求-響應(yīng)模型壁公,框架的目的就是幫助我們簡化開發(fā)感论,Spring Web MVC也是要簡化我們?nèi)粘eb開發(fā)的。
1.2 SpringMVC優(yōu)點(diǎn)
(1)清晰的角色劃分:
前端控制器(DispatcherServlet)
請求到處理器映射(HandlerMapping)
處理器適配器(HandlerAdapter)
視圖解析器(ViewResolver)
處理器或頁面控制器(Controller)
驗(yàn)證器(Validator)
命令對象(Command請求參數(shù)綁定到的對象就叫命令對象)
表單對象(Form Object提供給表單展示和提交到的對象就叫表單對象)紊册。
(2)分工明確比肄,而且擴(kuò)展點(diǎn)相當(dāng)靈活,可以很容易擴(kuò)展囊陡,雖然幾乎不需要芳绩;
(3)由于命令對象就是一個(gè)POJO,無需繼承框架特定API撞反,可以使用命令對象直接作為業(yè)務(wù)對象示括;
(4)和Spring 其他框架無縫集成,是其它Web框架所不具備的痢畜;
(5)可適配垛膝,通過HandlerAdapter可以支持任意的類作為處理器;
(6)可定制性丁稀,HandlerMapping吼拥、ViewResolver等能夠非常簡單的定制;
(7)功能強(qiáng)大的數(shù)據(jù)驗(yàn)證线衫、格式化凿可、綁定機(jī)制;
(8)利用Spring提供的Mock對象能夠非常簡單的進(jìn)行Web層單元測試授账;
(9)本地化枯跑、主題的解析的支持,使我們更容易進(jìn)行國際化和主題的切換白热。
(10)強(qiáng)大的JSP標(biāo)簽庫敛助,使JSP編寫更容易。
1.3 SpringMVC缺點(diǎn)
(1)jsp中要寫很多代碼屋确、控制器過于靈活纳击,缺少一個(gè)公用控制器
(2)Spring不支持分布式,這也是EJB仍然在用的原因之一
1.4 SpringMVC運(yùn)行流程
1攻臀、用戶發(fā)送請求至前端控制器DispatcherServlet焕数。
2、DispatcherServlet收到請求調(diào)用HandlerMapping處理器映射器刨啸。
3堡赔、處理器映射器找到具體的處理器(可以根據(jù)xml配置、注解進(jìn)行查找)设联,生成處理器對象及處理器攔截器(如果有則生成)一并返回給DispatcherServlet善已。
4灼捂、DispatcherServlet調(diào)用HandlerAdapter處理器適配器。
5雕拼、HandlerAdapter經(jīng)過適配調(diào)用具體的處理器(Controller纵东,也叫后端控制器)。
6啥寇、Controller執(zhí)行完成返回ModelAndView偎球。
7、HandlerAdapter將controller執(zhí)行結(jié)果ModelAndView返回給DispatcherServlet辑甜。
8衰絮、DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器。
9磷醋、ViewReslover解析后返回具體View猫牡。
10、DispatcherServlet根據(jù)View進(jìn)行渲染視圖(即將模型數(shù)據(jù)填充至視圖中)邓线。
11淌友、DispatcherServlet響應(yīng)用戶
1.5 SpringMVC本質(zhì)
(1)模型(Model):應(yīng)用程序所使用的特定域信息的表現(xiàn)形式
(2)視圖(View):域模型的表現(xiàn)形式(通過使用諸如輸入元素和按鈕之類的用戶界面元素,而這些元素與模型進(jìn)行交互)骇陈。
(3)控制器(Controller):主要負(fù)責(zé)解釋用戶的輸入并轉(zhuǎn)換為模型震庭,然后將轉(zhuǎn)換后的結(jié)果顯示給用戶。
具體流程圖如下:
(1)Spring MVC是一個(gè)基于動(dòng)作的MVC框架你雌。該框架突出了HTTP協(xié)議中的請求/響應(yīng)特性器联,在該框架中,用戶的每一個(gè)請求都聲明了一個(gè)需要執(zhí)行的動(dòng)作婿崭。而這主要是通過將每個(gè)請求URI映射到一個(gè)可執(zhí)行的方法來實(shí)現(xiàn)拨拓。同時(shí),也將請求參數(shù)映射到對應(yīng)方法的參數(shù)氓栈。
(2)SpringMVC 是Spring的一個(gè)子項(xiàng)目渣磷。
(3)Spring MVC提供了一種綁定機(jī)制,通過該機(jī)制可以從用戶請求中提取數(shù)據(jù)颤绕,然后將數(shù)據(jù)轉(zhuǎn)換為預(yù)定義的數(shù)據(jù)格式幸海,最后映射到一個(gè)模型類,從而創(chuàng)建一個(gè)對象奥务。該實(shí)現(xiàn)機(jī)制只需請求參數(shù)名稱與Java類的屬性相匹配即可。
(4)Spring MVC是視圖不可知的袜硫,他并沒有規(guī)定你的視圖必須使用哪種視圖技術(shù)氯葬,可以是JSP,也可以是Velocity模板婉陷、Tiles帚称、Freemarker以及XSLT等官研。
(5)Spring MVC是非侵入性的,因?yàn)闃I(yè)務(wù)邏輯代碼與框架本身是相分離的闯睹。
1.6 SpringMVC核心組件
1戏羽、前端控制器DispatcherServlet(不需要工程師開發(fā)),由框架提供
作用:接收請求,響應(yīng)結(jié)果楼吃,相當(dāng)于轉(zhuǎn)發(fā)器始花,中央處理器。有了dispatcherServlet減少了其它組件之間的耦合度孩锡。
用戶請求到達(dá)前端控制器酷宵,它就相當(dāng)于mvc模式中的c,dispatcherServlet是整個(gè)流程控制的中心躬窜,由它調(diào)用其它組件處理用戶的請求浇垦,dispatcherServlet的存在降低了組件之間的耦合性。
2荣挨、處理器映射器HandlerMapping(不需要工程師開發(fā)),由框架提供
作用:根據(jù)請求的url查找Handler
HandlerMapping負(fù)責(zé)根據(jù)用戶請求找到Handler即處理器男韧,springmvc提供了不同的映射器實(shí)現(xiàn)不同的映射方式,例如:配置文件方式默垄,實(shí)現(xiàn)接口方式此虑,注解方式等。
3厕倍、處理器適配器HandlerAdapter
作用:按照特定規(guī)則(HandlerAdapter要求的規(guī)則)去執(zhí)行Handler
通過HandlerAdapter對處理器進(jìn)行執(zhí)行寡壮,這是適配器模式的應(yīng)用,通過擴(kuò)展適配器可以對更多類型的處理器進(jìn)行執(zhí)行讹弯。
4况既、處理器Handler(需要工程師開發(fā))
注意:編寫Handler時(shí)按照HandlerAdapter的要求去做,這樣適配器才可以去正確執(zhí)行Handler
Handler是繼DispatcherServlet前端控制器的后端控制器组民,在DispatcherServlet的控制下Handler對具體的用戶請求進(jìn)行處理棒仍。
由于Handler涉及到具體的用戶業(yè)務(wù)請求,所以一般情況需要工程師根據(jù)業(yè)務(wù)需求開發(fā)Handler臭胜。
5莫其、視圖解析器View resolver(不需要工程師開發(fā)),由框架提供
作用:進(jìn)行視圖解析,根據(jù)邏輯視圖名解析成真正的視圖(view)
View Resolver負(fù)責(zé)將處理結(jié)果生成View視圖耸三,View Resolver首先根據(jù)邏輯視圖名解析成物理視圖名即具體的頁面地址乱陡,再生成View視圖對象,最后對View進(jìn)行渲染將處理結(jié)果通過頁面展示給用戶仪壮。 springmvc框架提供了很多的View視圖類型憨颠,包括:jstlView、freemarkerView、pdfView等爽彤。
一般情況下需要通過頁面標(biāo)簽或頁面模版技術(shù)將模型數(shù)據(jù)通過頁面展示給用戶养盗,需要由工程師根據(jù)業(yè)務(wù)需求開發(fā)具體的頁面。
6适篙、視圖View(需要工程師開發(fā)jsp...)
View是一個(gè)接口往核,實(shí)現(xiàn)類支持不同的View類型(jsp、freemarker嚷节、pdf...)
1.7 SpringMVC具體流程步驟
1聂儒、首先用戶發(fā)送請求——>DispatcherServlet,前端控制器收到請求后自己不進(jìn)行處理丹喻,而是委托給其他的解析器進(jìn)行處理薄货,作為統(tǒng)一訪問點(diǎn),進(jìn)行全局的流程控制碍论;
2谅猾、DispatcherServlet——>HandlerMapping, HandlerMapping 將會(huì)把請求映射為HandlerExecutionChain 對象(包含一個(gè)Handler 處理器(頁面控制器)對象鳍悠、多個(gè)HandlerInterceptor 攔截器)對象税娜,通過這種策略模式,很容易添加新的映射策略藏研;
3敬矩、DispatcherServlet——>HandlerAdapter,HandlerAdapter 將會(huì)把處理器包裝為適配器蠢挡,從而支持多種類型的處理器弧岳,即適配器設(shè)計(jì)模式的應(yīng)用,從而很容易支持很多類型的處理器业踏;
4禽炬、HandlerAdapter——>處理器功能處理方法的調(diào)用,HandlerAdapter 將會(huì)根據(jù)適配的結(jié)果調(diào)用真正的處理器的功能處理方法勤家,完成功能處理腹尖;并返回一個(gè)ModelAndView 對象(包含模型數(shù)據(jù)、邏輯視圖名)伐脖;
5热幔、ModelAndView的邏輯視圖名——> ViewResolver, ViewResolver 將把邏輯視圖名解析為具體的View讼庇,通過這種策略模式绎巨,很容易更換其他視圖技術(shù);
6蠕啄、View——>渲染认烁,View會(huì)根據(jù)傳進(jìn)來的Model模型數(shù)據(jù)進(jìn)行渲染,此處的Model實(shí)際是一個(gè)Map數(shù)據(jù)結(jié)構(gòu)介汹,因此很容易支持其他視圖技術(shù)却嗡;
7、返回控制權(quán)給DispatcherServlet嘹承,由DispatcherServlet返回響應(yīng)給用戶窗价,到此一個(gè)流程結(jié)束。
二叹卷、SpringMVC的九大組件
2.1 HandlerMapping
是用來查找Handler的撼港。在SpringMVC中會(huì)有很多請求,每個(gè)請求都需要一個(gè)Handler處理骤竹,具體接收到一個(gè)請求之后使用哪個(gè)Handler進(jìn)行處理呢帝牡?這就是HandlerMapping需要做的事。
2.2 HandlerAdapter
從名字上看蒙揣,它就是一個(gè)適配器靶溜。因?yàn)镾pringMVC中的Handler可以是任意的形式,只要能處理請求就ok懒震,但是Servlet需要的處理方法的結(jié)構(gòu)卻是固定的罩息,都是以request和response為參數(shù)的方法。如何讓固定的Servlet處理方法調(diào)用靈活的Handler來進(jìn)行處理呢个扰?這就是HandlerAdapter要做的事情瓷炮。
小結(jié):Handler是用來干活的工具;HandlerMapping用于根據(jù)需要干的活找到相應(yīng)的工具递宅;HandlerAdapter是使用工具干活的人娘香。
2.3 HandlerExceptionResolver
其它組件都是用來干活的。在干活的過程中難免會(huì)出現(xiàn)問題办龄,出問題后怎么辦呢烘绽?這就需要有一個(gè)專門的角色對異常情況進(jìn)行處理,在SpringMVC中就是HandlerExceptionResolver土榴。具體來說诀姚,此組件的作用是根據(jù)異常設(shè)置ModelAndView,之后再交給render方法進(jìn)行渲染玷禽。
2.4 ViewResolver
ViewResolver用來將String類型的視圖名和Locale解析為View類型的視圖赫段。View是用來渲染頁面的,也就是將程序返回的參數(shù)填入模板里矢赁,生成html(也可能是其它類型)文件糯笙。這里就有兩個(gè)關(guān)鍵問題:使用哪個(gè)模板?用什么技術(shù)(規(guī)則)填入?yún)?shù)撩银?這其實(shí)是ViewResolver主要要做的工作给涕,ViewResolver需要找到渲染所用的模板和所用的技術(shù)(也就是視圖的類型)進(jìn)行渲染,具體的渲染過程則交由不同的視圖自己完成。
2.5 RequestToViewNameTranslator
ViewName是根據(jù)ViewName查找View够庙,但有的Handler處理完后并沒有設(shè)置View也沒有設(shè)置ViewName恭应,這時(shí)就需要從request獲取ViewName了,如何從request中獲取ViewName就是RequestToViewNameTranslator要做的事情了耘眨。RequestToViewNameTranslator在Spring MVC容器里只可以配置一個(gè)昼榛,所以所有request到ViewName的轉(zhuǎn)換規(guī)則都要在一個(gè)Translator里面全部實(shí)現(xiàn)。
2.6 LocaleResolver
解析視圖需要兩個(gè)參數(shù):一是視圖名剔难,另一個(gè)是Locale胆屿。視圖名是處理器返回的,Locale是從哪里來的偶宫?這就是LocaleResolver要做的事情非迹。LocaleResolver用于從request解析出Locale,Locale就是zh-cn之類纯趋,表示一個(gè)區(qū)域憎兽,有了這個(gè)就可以對不同區(qū)域的用戶顯示不同的結(jié)果。SpringMVC主要有兩個(gè)地方用到了Locale:一是ViewResolver視圖解析的時(shí)候结闸;二是用到國際化資源或者主題的時(shí)候唇兑。
2.7 ThemeResolver
用于解析主題。SpringMVC中一個(gè)主題對應(yīng)一個(gè)properties文件桦锄,里面存放著跟當(dāng)前主題相關(guān)的所有資源扎附、如圖片、css樣式等结耀。SpringMVC的主題也支持國際化留夜,同一個(gè)主題不同區(qū)域也可以顯示不同的風(fēng)格。SpringMVC中跟主題相關(guān)的類有 ThemeResolver图甜、ThemeSource和Theme碍粥。主題是通過一系列資源來具體體現(xiàn)的,要得到一個(gè)主題的資源黑毅,首先要得到資源的名稱嚼摩,這是ThemeResolver的工作。然后通過主題名稱找到對應(yīng)的主題(可以理解為一個(gè)配置)文件矿瘦,這是ThemeSource的工作枕面。最后從主題中獲取資源就可以了。
2.8 MultipartResolver
用于處理上傳請求缚去。處理方法是將普通的request包裝成MultipartHttpServletRequest潮秘,后者可以直接調(diào)用getFile方法獲取File,如果上傳多個(gè)文件易结,還可以調(diào)用getFileMap得到FileName->File結(jié)構(gòu)的Map枕荞。此組件中一共有三個(gè)方法柜候,作用分別是判斷是不是上傳請求,將request包裝成MultipartHttpServletRequest躏精、處理完后清理上傳過程中產(chǎn)生的臨時(shí)資源渣刷。
2.9 FlashMapManager
用來管理FlashMap的,F(xiàn)lashMap主要用在redirect中傳遞參數(shù)玉控。
三飞主、參考文章
參考博客:
https://blog.csdn.net/xia4820723/article/details/51418676