1. Sping MVC簡介
1.1 MVC體系結(jié)構(gòu)
三層架構(gòu)
在JavaEE開發(fā)中睛藻,幾乎全都是基于B/S架構(gòu)的開發(fā)蓄诽。在B/S架構(gòu)中功偿,系統(tǒng)標(biāo)準(zhǔn)的三層架構(gòu)包括:表現(xiàn)層筑舅、業(yè)務(wù)層座慰、持久層。
三層架構(gòu)中豁翎,每一層各司其職:
- 表現(xiàn)層:
表現(xiàn)層是我們常說的web層角骤。它負(fù)責(zé)接收客戶端請求隅忿,向客戶端響應(yīng)結(jié)果心剥,通常客戶端使用http協(xié)議請求web層背桐,web需要接收http請求优烧,完成http響應(yīng)。
表現(xiàn)層包括展示層和控制層:控制層負(fù)責(zé)接收請求链峭,展示層負(fù)責(zé)結(jié)果的展示畦娄。
表現(xiàn)層依賴業(yè)務(wù)層,接收到客戶端請求一般會調(diào)用業(yè)務(wù)層進(jìn)行業(yè)務(wù)處理,并將處理結(jié)果響應(yīng)給客戶端熙卡。
表現(xiàn)層設(shè)計(jì)一般都使用MVC模型杖刷。(MVC是表現(xiàn)層的設(shè)計(jì)模型,和其他層沒有關(guān)系) - 業(yè)務(wù)層:
業(yè)務(wù)層是我們常說的service層驳癌。它負(fù)責(zé)業(yè)務(wù)邏輯處理滑燃,和開發(fā)項(xiàng)目的需求息息相關(guān)。web層依賴業(yè)務(wù)層颓鲜,但是業(yè)務(wù)層不依賴web層表窘。
業(yè)務(wù)層在處理業(yè)務(wù)時(shí)可能會依賴持久層,如果要對數(shù)據(jù)持久化需要保證事物一致性甜滨。(也就是我們說的乐严,事物應(yīng)該放到業(yè)務(wù)層來控制) - 持久層:
也就是我們常說的dao層。負(fù)責(zé)數(shù)據(jù)持久化衣摩,包括數(shù)據(jù)層即數(shù)據(jù)庫和數(shù)據(jù)訪問昂验,數(shù)據(jù)庫是對數(shù)據(jù)進(jìn)行持久化的載體,數(shù)據(jù)訪問層是業(yè)務(wù)層和持久層交互的接口昭娩,業(yè)務(wù)層需要通過數(shù)據(jù)訪問層將數(shù)據(jù)持久化到數(shù)據(jù)庫中凛篙,通俗的講栏渺,持久層就是和數(shù)據(jù)庫交互呛梆,對數(shù)據(jù)庫表進(jìn)行增刪改查的。
MVC設(shè)計(jì)模式
MVC全名是Model View Controller磕诊,是模型(model)--視圖(view)--控制器(controller)的縮寫莱褒,是一種利用設(shè)計(jì)創(chuàng)建Web應(yīng)用程序表現(xiàn)層的模式击困。MVC中每個(gè)部分各司其職: - Model(模型):模型包含業(yè)務(wù)模型和數(shù)據(jù)模型,數(shù)據(jù)模型用于封裝數(shù)據(jù)广凸,業(yè)務(wù)模型用于處理業(yè)務(wù)阅茶。
- View(視圖):通常指的就是我們的jsp或者h(yuǎn)tml。作用一般就是展示數(shù)據(jù)的谅海。通常視圖3是依據(jù)模型數(shù)據(jù)創(chuàng)建的脸哀。
- Controller(控制器):是應(yīng)用程序處理用戶交互的部分。作用一般就是處理程序邏輯的扭吁。
MVC提倡:每一層只編寫自己的東西撞蜂,不編寫任何其他代碼盲镶;分層是為了解耦,解耦是為了維護(hù)方便和分工協(xié)作蝌诡。
1.2 Spring MVC是什么
SpringMVC全名叫做Spring Web MVC溉贿,是一種基于Java的實(shí)現(xiàn)MVC設(shè)計(jì)模式的請求驅(qū)動(dòng)類型的輕量級Web框架,屬于SpringFrameWork的后續(xù)產(chǎn)品浦旱。
SpringMVC已經(jīng)成為目前最主流的MVC框架之一顽照,并且隨著Spring3.0的發(fā)布,全面超越Struts2闽寡,成為最優(yōu)秀的MVC框架代兵。
Spring MVC本質(zhì)可以認(rèn)為是對servlet的封裝,簡化了我們serlvet的開發(fā)爷狈。SpringMVC中要讓一個(gè)Java類能夠處理請求只需要添加注解就ok植影,它通過一套注解,讓一個(gè)簡單的Java類成為處理請求的控制器涎永,而無需實(shí)現(xiàn)任何接口思币。同時(shí)它還支持RESTful編程風(fēng)格的請求。
2. Spring Web MVC 工作流程
2.1. Spring MVC 請求處理流程
流程處理說明
- 用戶發(fā)送請求至前端控制器DispatcherServlet羡微;
- DispatcherServlet收到請求調(diào)用HandlerMapping處理器映射器谷饿;
- 處理器映射器根據(jù)請求的url找到具體的Handler(后端控制器),生成處理器對象以及處理器攔截器(如果有則生成)一并返回DispatcherServlet妈倔;
- DispatcherServlet調(diào)用HandlerAdapter處理器適配器去調(diào)用Handler博投;
- 處理器適配器執(zhí)行Handler;
- Handler執(zhí)行完成給處理器適配器返回ModelAndView盯蝴;
- 處理器適配器向前端控制器返回ModelAndView毅哗,ModelAndView是SpringMVC框架的一個(gè)底層對象,包括Model和View捧挺;
- 前端控制器請求視圖解析器3去進(jìn)行視圖解析虑绵,根據(jù)邏輯視圖名來解析真正的視圖;
- 視圖解析器向前端控制器返回View闽烙;
- 前端控制器進(jìn)行視圖渲染翅睛,將模型數(shù)據(jù)(在ModelAndView對象中)填充到request域;
- 前端控制器向用戶響應(yīng)3結(jié)果黑竞。
2.2. Spring MVC 九大組件
- HandlerMapping(處理器映射器)
HandlerMapping 是用來查找Hander的捕发,也就是處理器,具體的表現(xiàn)形式可以是類摊溶,也可以是方法爬骤,比如充石,標(biāo)注了@RequestMapping的每個(gè)方法都可以看成是一個(gè)Hander莫换。Hander負(fù)責(zé)具體實(shí)際的處理請求霞玄,在請求到達(dá)后,HanderMapping的作用便是找到請求相應(yīng)的處理器Hander和Interceptor拉岁。 - HanderAdapter(處理器適配器)
HanderAdapter是一個(gè)適配器坷剧。因?yàn)镾pring MVC中Hander可以是任意形式的,只要能處理請求即可喊暖。但是把請求交給Servlet的時(shí)候惫企,由于Servlet的方法結(jié)構(gòu)都是doService(HttpServletRequest req,HttpServletResponse resp)形式的,要讓固定的Servlet處理方法調(diào)用Hander來進(jìn)行處理陵叽,便是HandlerAdapter的職責(zé)狞尔。 - HandlerExecptionResoler
HandlerExectionResoler用于處理Handler產(chǎn)生的異常情況。它的作用是根據(jù)異常設(shè)置ModelAndView巩掺,之后交給渲染方法進(jìn)行渲染偏序,渲染方法會將ModelAndView渲染成頁面。 - ViewResoler
ViewResoler即視圖解析器胖替,用于將Spring類型的視圖名和Locale解析為View類型的視圖研儒,只有一個(gè)resolveViewName()方法。從方法的定義可以看出独令,Controller層返回的String類型視圖名viewName最終會在這里被解析成View端朵。View是用來渲染頁面的,也就是說燃箭,它會將程序返回的參數(shù)和數(shù)據(jù)填入模版中冲呢,生成html文件。ViewResolver在這個(gè)過程主要完成兩件事情:ViewResolver找到渲染所用的模版(第一件大事)和所用的技術(shù)(第二件大事招狸,其實(shí)也就是找到視圖類型碗硬,如JSP)并填入?yún)?shù)。默認(rèn)情況下瓢颅,SpringMVC會自動(dòng)為我們配置一個(gè)InternalResourceViewResolver恩尾,是針對jsp類型視圖的。 - RequestToViewNameTranslator
RequestToViewNameTranslator組件的作用是從請求中獲取ViewName挽懦。因?yàn)閂iewResolver根據(jù)ViewName查找View翰意,但有的Handler處理完成之后,沒有設(shè)置View信柿,也沒有設(shè)置ViewName冀偶,便要通過這個(gè)組件從請求中查找ViewName。 - LocaleResolver
ViewResolver組件的resolverViewName方法需要兩個(gè)參數(shù)渔嚷,一個(gè)是視圖3名进鸠,一個(gè)是Locale。LocaleResolver用于從請求中解析出Locale形病,比如中國Locale是zh-CN客年,用來表示一個(gè)區(qū)域霞幅。這個(gè)組件也是i18n的基礎(chǔ)。 - ThemeResolver
ThemeResolver組件是用來解析主題的量瓜。主題是樣式3司恳、圖片及他們所形成的顯示效果的集合。 - MultipartResolver
MultipartResolver用于上傳請求绍傲,通過將普通的請求包裝成MultipartHttpServletRequest來實(shí)現(xiàn)扔傅。MultipartHttpServletRequest可以通過getFile()方法直接獲得文件。如果上傳多個(gè)文件烫饼,還可以調(diào)用getFileMap()方法獲得到Map<FileName,File>這樣的結(jié)構(gòu)猎塞,MultipartResolver的作用就是封裝普通的請求,使其擁有文件上傳的功能杠纵。 - FlashMapManager
FlashMap用于重定向時(shí)的參數(shù)傳遞邢享,比如在處理用戶訂單時(shí)候,為了避免重復(fù)提交淡诗,可以處理完post請求之后重定向到一個(gè)get請求骇塘,這個(gè)get請求可以用來顯示訂單詳情之類的信息。這樣做雖然可以規(guī)避用戶重新提交訂單的問題韩容,但是在這個(gè)頁面上要顯示訂單的信息款违,這些數(shù)據(jù)從哪里來獲得呢?因?yàn)橹囟ㄏ驎r(shí)沒有傳遞參數(shù)這一功能的群凶,如果不想把參數(shù)寫進(jìn)URL(不推薦)插爹,那么就可以通過FlashMap來傳遞。只需要在重定向之前將要傳遞的數(shù)據(jù)寫入請求(可以通過ServletRequestAttributes.getRequest()方法獲得)的屬性PUTPUT_FLASH_MAP_ATTRIBUTE中请梢,這樣在重定向之后的Handler中Spring就會自動(dòng)將其設(shè)置到Model中赠尾,在顯示訂單信息的頁面上就可以直接從Model中獲取數(shù)據(jù)。FlashMapManager就是用來管理FalshMap的毅弧。