小編給大家分享一下SpringMVC如何實(shí)現(xiàn),相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
專注于為中小企業(yè)提供成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、外貿(mào)營銷網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)冊(cè)亨免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了近千家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。在Web世界里,具體步驟如下:
1、 Web瀏覽器(如IE)發(fā)起請(qǐng)求,如訪問 http://sishuok.com
2、 Web服務(wù)器(如Tomcat)接收請(qǐng)求,處理請(qǐng)求(比如用戶新增,則將把用戶保存一下),最后產(chǎn)生響應(yīng)(一般為html)。
3、web服務(wù)器處理完成后,返回內(nèi)容給web客戶端(一般就是我們的瀏覽器),客戶端對(duì)接收的內(nèi)容進(jìn)行處理(如web瀏覽器將會(huì)對(duì)接收到的html內(nèi)容進(jìn)行渲染以展示給客戶)。
因此,在Web世界里:
都是Web客戶端發(fā)起請(qǐng)求,Web服務(wù)器接收、處理并產(chǎn)生響應(yīng)。
一般Web服務(wù)器是不能主動(dòng)通知Web客戶端更新內(nèi)容。雖然現(xiàn)在有些技術(shù)如服務(wù)器推(如Comet)、還有現(xiàn)在的HTML5 websocket可以實(shí)現(xiàn)Web服務(wù)器主動(dòng)通知Web客戶端。
到此我們了解了在web開發(fā)時(shí)的請(qǐng)求/響應(yīng)模型,接下來我們看一下標(biāo)準(zhǔn)的MVC模型是什么。
**MVC模型:**是一種架構(gòu)型的模式,本身不引入新功能,只是幫助我們將開發(fā)的結(jié)構(gòu)組織的更加合理,使展示與模型分離、流程控制邏輯、業(yè)務(wù)邏輯調(diào)用與展示邏輯分離。如圖1-2
圖1-2
首先讓我們了解下MVC(Model-View-Controller)三元組的概念:
**Model(模型):**數(shù)據(jù)模型,提供要展示的數(shù)據(jù),因此包含數(shù)據(jù)和行為,可以認(rèn)為是領(lǐng)域模型或JavaBean組件(包含數(shù)據(jù)和行為),不過現(xiàn)在一般都分離開來:Value Object(數(shù)據(jù)) 和 服務(wù)層(行為)。也就是模型提供了模型數(shù)據(jù)查詢和模型數(shù)據(jù)的狀態(tài)更新等功能,包括數(shù)據(jù)和業(yè)務(wù)。
**View(視圖):**負(fù)責(zé)進(jìn)行模型的展示,一般就是我們見到的用戶界面,客戶想看到的東西。
**Controller(控制器):**接收用戶請(qǐng)求,委托給模型進(jìn)行處理(狀態(tài)改變),處理完畢后把返回的模型數(shù)據(jù)返回給視圖,由視圖負(fù)責(zé)展示。 也就是說控制器做了個(gè)調(diào)度員的工作,。
從圖1-1我們還看到,在標(biāo)準(zhǔn)的MVC中模型能主動(dòng)推數(shù)據(jù)給視圖進(jìn)行更新(觀察者設(shè)計(jì)模式,在模型上注冊(cè)視圖,當(dāng)模型更新時(shí)自動(dòng)更新視圖),但在Web開發(fā)中模型是無法主動(dòng)推給視圖(無法主動(dòng)更新用戶界面),因?yàn)樵赪eb開發(fā)是請(qǐng)求-響應(yīng)模型。
那接下來我們看一下在Web里MVC是什么樣子,我們稱其為 Web MVC 來區(qū)別標(biāo)準(zhǔn)的MVC。
模型-視圖-控制器概念和標(biāo)準(zhǔn)MVC概念一樣,請(qǐng)參考1.2,我們?cè)倏匆幌耊eb MVC標(biāo)準(zhǔn)架構(gòu),如圖1-3:
如圖1-3
在Web MVC模式下,模型無法主動(dòng)推數(shù)據(jù)給視圖,如果用戶想要視圖更新,需要再發(fā)送一次請(qǐng)求(即請(qǐng)求-響應(yīng)模型)。
概念差不多了,我們接下來了解下Web端開發(fā)的發(fā)展歷程,和使用代碼來演示一下Web MVC是如何實(shí)現(xiàn)的,還有為什么要使用MVC這個(gè)模式呢?
此處我們只是簡單的敘述比較核心的歷程,如圖1-4
圖1-4
1.4.1、CGI:(Common Gateway Interface)公共網(wǎng)關(guān)接口,一種在web服務(wù)端使用的腳本技術(shù),使用C或Perl語言編寫,用于接收web用戶請(qǐng)求并處理,最后動(dòng)態(tài)產(chǎn)生響應(yīng)給用戶,但每次請(qǐng)求將產(chǎn)生一個(gè)進(jìn)程,重量級(jí)。
1.4.2、Servlet:一種JavaEE web組件技術(shù),是一種在服務(wù)器端執(zhí)行的web組件,用于接收web用戶請(qǐng)求并處理,最后動(dòng)態(tài)產(chǎn)生響應(yīng)給用戶。但每次請(qǐng)求只產(chǎn)生一個(gè)線程(而且有線程池),輕量級(jí)。而且能利用許多JavaEE技術(shù)(如JDBC等)。本質(zhì)就是在java代碼里面 輸出 html流。但表現(xiàn)邏輯、控制邏輯、業(yè)務(wù)邏輯調(diào)用混雜。如圖1-5
圖1-5
如圖1-5,這種做法是絕對(duì)不可取的,控制邏輯、表現(xiàn)代碼、業(yè)務(wù)邏輯對(duì)象調(diào)用混雜在一起,大的問題是直接在Java代碼里面輸出Html,這樣前端開發(fā)人員無法進(jìn)行頁面風(fēng)格等的設(shè)計(jì)與修改,即使修改也是很麻煩,因此實(shí)際項(xiàng)目這種做法不可取。
1.4.3、JSP:(Java Server Page):一種在服務(wù)器端執(zhí)行的web組件,是一種運(yùn)行在標(biāo)準(zhǔn)的HTML頁面中嵌入腳本語言(現(xiàn)在只支持Java)的模板頁面技術(shù)。本質(zhì)就是在html代碼中嵌入java代碼。JSP最終還是會(huì)被編譯為Servlet,只不過比純Servlet開發(fā)頁面更簡單、方便。但表現(xiàn)邏輯、控制邏輯、業(yè)務(wù)邏輯調(diào)用還是混雜。如圖1-6
圖1-6
如圖1-6,這種做法也是絕對(duì)不可取的,控制邏輯、表現(xiàn)代碼、業(yè)務(wù)邏輯對(duì)象調(diào)用混雜在一起,但比直接在servlet里輸出html要好一點(diǎn),前端開發(fā)人員可以進(jìn)行簡單的頁面風(fēng)格等的設(shè)計(jì)與修改(但如果嵌入的java腳本太多也是很難修改的),因此實(shí)際項(xiàng)目這種做法不可取。
JSP本質(zhì)還是Servlet,最終在運(yùn)行時(shí)會(huì)生成一個(gè)Servlet(如tomcat,將在tomcat\work\Catalina\web應(yīng)用名\org\apache\jsp下生成),但這種使得寫html簡單點(diǎn),但仍是控制邏輯、表現(xiàn)代碼、業(yè)務(wù)邏輯對(duì)象調(diào)用混雜在一起。
**1.4.4、Model1:**可以認(rèn)為是JSP的增強(qiáng)版,可以認(rèn)為是jsp+javabean如圖1-7
特點(diǎn):使用 jsp:useBean標(biāo)準(zhǔn)動(dòng)作,自動(dòng)將請(qǐng)求參數(shù)封裝為JavaBean組件;還必須使用java腳本執(zhí)行控制邏輯。
圖1-7
此處我們可以看出,使用 jsp:useBean標(biāo)準(zhǔn)動(dòng)作可以簡化javabean的獲取/創(chuàng)建,及將請(qǐng)求參數(shù)封裝到j(luò)avabean,再看一下Model1架構(gòu),如圖1-8。
圖1-8 Model1架構(gòu)
Model1架構(gòu)中,JSP負(fù)責(zé)控制邏輯、表現(xiàn)邏輯、業(yè)務(wù)對(duì)象(javabean)的調(diào)用,只是比純JSP簡化了獲取請(qǐng)求參數(shù)和封裝請(qǐng)求參數(shù)。同樣是不好的,在項(xiàng)目中應(yīng)該嚴(yán)禁使用(或最多再demo里使用)。
1.4.5、Model2:在JavaEE世界里,它可以認(rèn)為就是Web MVC模型
Model2架構(gòu)其實(shí)可以認(rèn)為就是我們所說的Web MVC模型,只是控制器采用Servlet、模型采用JavaBean、視圖采用JSP,如圖1-9
圖1-9 Model2架構(gòu)
具體代碼事例如下:
從Model2架構(gòu)可以看出,視圖和模型分離了,控制邏輯和展示邏輯分離了。
但我們也看到嚴(yán)重的缺點(diǎn):
1. 1、控制器:
1.1.1、控制邏輯可能比較復(fù)雜,其實(shí)我們可以按照規(guī)約,如請(qǐng)求參數(shù)submitFlag=toAdd,我們其實(shí)可以直接調(diào)用toAdd方法,來簡化控制邏輯;而且每個(gè)模塊基本需要一個(gè)控制器,造成控制邏輯可能很復(fù)雜;
1.1.2、請(qǐng)求參數(shù)到模型的封裝比較麻煩,如果能交給框架來做這件事情,我們可以從中得到解放;
1.1.3、選擇下一個(gè)視圖,嚴(yán)重依賴Servlet API,這樣很難或基本不可能更換視圖;
1.1.4、給視圖傳輸要展示的模型數(shù)據(jù),使用Servlet API,更換視圖技術(shù)也要一起更換,很麻煩。
1.2、模型:
1.2.1、此處模型使用JavaBean,可能造成JavaBean組件類很龐大,一般現(xiàn)在項(xiàng)目都是采用三層架構(gòu),而不采用JavaBean。
1.3、視圖
1.3.1、現(xiàn)在被綁定在JSP,很難更換視圖,比如Velocity、FreeMarker;比如我要支持Excel、PDF視圖等等。
1.4.5、服務(wù)到工作者:Front Controller + Application Controller + Page Controller + Context
即,前端控制器+應(yīng)用控制器+頁面控制器(也有稱其為動(dòng)作)+上下文,也是Web MVC,只是責(zé)任更加明確,詳情請(qǐng)參考《核心J2EE設(shè)計(jì)模式》和《企業(yè)應(yīng)用架構(gòu)模式》如圖1-10:
圖1-10
運(yùn)行流程如下:
職責(zé):
**Front Controller:**前端控制器,負(fù)責(zé)為表現(xiàn)層提供統(tǒng)一訪問點(diǎn),從而避免Model2中出現(xiàn)的重復(fù)的控制邏輯(由前端控制器統(tǒng)一回調(diào)相應(yīng)的功能方法,如前邊的根據(jù)submitFlag=login轉(zhuǎn)調(diào)login方法);并且可以為多個(gè)請(qǐng)求提供共用的邏輯(如準(zhǔn)備上下文等等),將選擇具體視圖和具體的功能處理(如login里邊封裝請(qǐng)求參數(shù)到模型,并調(diào)用業(yè)務(wù)邏輯對(duì)象)分離。
**Application Controller:**應(yīng)用控制器,前端控制器分離選擇具體視圖和具體的功能處理之后,需要有人來管理,應(yīng)用控制器就是用來選擇具體視圖技術(shù)(視圖的管理)和具體的功能處理(頁面控制器/命令對(duì)象/動(dòng)作管理),一種策略設(shè)計(jì)模式的應(yīng)用,可以很容易的切換視圖/頁面控制器,相互不產(chǎn)生影響。
**Page Controller(Command):**頁面控制器/動(dòng)作/處理器:功能處理代碼,收集參數(shù)、封裝參數(shù)到模型,轉(zhuǎn)調(diào)業(yè)務(wù)對(duì)象處理模型,返回邏輯視圖名交給前端控制器(和具體的視圖技術(shù)解耦),由前端控制器委托給應(yīng)用控制器選擇具體的視圖來展示,可以是命令設(shè)計(jì)模式的實(shí)現(xiàn)。頁面控制器也被稱為處理器或動(dòng)作。
**Context:**上下文,還記得Model2中為視圖準(zhǔn)備要展示的模型數(shù)據(jù)嗎,我們直接放在request中(Servlet API相關(guān)),有了上下文之后,我們就可以將相關(guān)數(shù)據(jù)放置在上下文,從而與協(xié)議無關(guān)(如Servlet API)的訪問/設(shè)置模型數(shù)據(jù),一般通過ThreadLocal模式實(shí)現(xiàn)。
到此,我們回顧了整個(gè)web開發(fā)架構(gòu)的發(fā)展歷程,可能不同的web層框架在細(xì)節(jié)處理方面不同,但的目的是一樣的:
干凈的web表現(xiàn)層:
模型和視圖的分離;
控制器中的控制邏輯與功能處理分離(收集并封裝參數(shù)到模型對(duì)象、業(yè)務(wù)對(duì)象調(diào)用);
控制器中的視圖選擇與具體視圖技術(shù)分離。
輕薄的web表現(xiàn)層:
做的事情越少越好,薄薄的,不應(yīng)該包含無關(guān)代碼;
只負(fù)責(zé)收集并組織參數(shù)到模型對(duì)象,啟動(dòng)業(yè)務(wù)對(duì)象的調(diào)用;
控制器只返回邏輯視圖名并由相應(yīng)的應(yīng)用控制器來選擇具體使用的視圖策略;
盡量少使用框架特定API,保證容易測(cè)試。
到此我們了解Web MVC的發(fā)展歷程,接下來讓我們了解下Spring MVC到底是什么、架構(gòu)及來個(gè)HelloWorld了解下具體怎么使用吧。
本章具體代碼請(qǐng)參考 springmvc-chapter1工程。
Spring Web MVC是一種基于Java的實(shí)現(xiàn)了Web MVC設(shè)計(jì)模式的請(qǐng)求驅(qū)動(dòng)類型的輕量級(jí)Web框架,即使用了MVC架構(gòu)模式的思想,將web層進(jìn)行職責(zé)解耦,基于請(qǐng)求驅(qū)動(dòng)指的就是使用請(qǐng)求-響應(yīng)模型,框架的目的就是幫助我們簡化開發(fā),Spring Web MVC也是要簡化我們?nèi)粘eb開發(fā)的。
另外還有一種基于組件的、事件驅(qū)動(dòng)的Web框架在此就不介紹了,如Tapestry、JSF等。
Spring Web MVC也是服務(wù)到工作者模式的實(shí)現(xiàn),但進(jìn)行可優(yōu)化。前端控制器是DispatcherServlet;
應(yīng)用控制器其實(shí)拆為處理器映射器(Handler Mapping)進(jìn)行處理器管理和視圖解析器(View Resolver)進(jìn)行視圖管理;頁面控制器/動(dòng)作/處理器為Controller接口(僅包含ModelAndView handleRequest(request, response)
方法)的實(shí)現(xiàn)(也可以是任何的POJO類);支持本地化(Locale)解析、主題(Theme)解析及文件上傳等;提供了非常靈活的數(shù)據(jù)驗(yàn)證、格式化和數(shù)據(jù)綁定機(jī)制;提供了強(qiáng)大的約定大于配置(慣例優(yōu)先原則)的契約式編程支持。
√讓我們能非常簡單的設(shè)計(jì)出干凈的Web層和薄薄的Web層;
√進(jìn)行更簡潔的Web層的開發(fā);
√天生與Spring框架集成(如IoC容器、AOP等);
√提供強(qiáng)大的約定大于配置的契約式編程支持;
√能簡單的進(jìn)行Web層的單元測(cè)試;
√支持靈活的URL到頁面控制器的映射;
√非常容易與其他視圖技術(shù)集成,如Velocity、FreeMarker等等,因?yàn)槟P蛿?shù)據(jù)不放在特定的API里,而是放在一個(gè)Model里(Map
數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn),因此很容易被其他框架使用);
√非常靈活的數(shù)據(jù)驗(yàn)證、格式化和數(shù)據(jù)綁定機(jī)制,能使用任何對(duì)象進(jìn)行數(shù)據(jù)綁定,不必實(shí)現(xiàn)特定框架的API;
√提供一套強(qiáng)大的JSP標(biāo)簽庫,簡化JSP開發(fā);
√支持靈活的本地化、主題等解析;
√更加簡單的異常處理;
√對(duì)靜態(tài)資源的支持;
√支持Restful風(fēng)格。
Spring Web MVC框架也是一個(gè)基于請(qǐng)求驅(qū)動(dòng)的Web框架,并且也使用了前端控制器模式來進(jìn)行設(shè)計(jì),再根據(jù)請(qǐng)求映射規(guī)則分發(fā)給相應(yīng)的頁面控制器(動(dòng)作/處理器)進(jìn)行處理。首先讓我們整體看一下Spring Web MVC處理請(qǐng)求的流程:
如圖2-1
圖2-1
具體執(zhí)行步驟如下:
1、 首先用戶發(fā)送請(qǐng)求————>前端控制器,前端控制器根據(jù)請(qǐng)求信息(如URL)來決定選擇哪一個(gè)頁面控制器進(jìn)行處理并把請(qǐng)求委托給它,即以前的控制器的控制邏輯部分;圖2-1中的1、2步驟;
2、 頁面控制器接收到請(qǐng)求后,進(jìn)行功能處理,首先需要收集和綁定請(qǐng)求參數(shù)到一個(gè)對(duì)象,這個(gè)對(duì)象在Spring Web MVC中叫命令對(duì)象,并進(jìn)行驗(yàn)證,然后將命令對(duì)象委托給業(yè)務(wù)對(duì)象進(jìn)行處理;處理完畢后返回一個(gè)ModelAndView(模型數(shù)據(jù)和邏輯視圖名);圖2-1中的3、4、5步驟;
3、 前端控制器收回控制權(quán),然后根據(jù)返回的邏輯視圖名,選擇相應(yīng)的視圖進(jìn)行渲染,并把模型數(shù)據(jù)傳入以便視圖渲染;圖2-1中的步驟6、7;
4、 前端控制器再次收回控制權(quán),將響應(yīng)返回給用戶,圖2-1中的步驟8;至此整個(gè)結(jié)束。
問題:
1、 請(qǐng)求如何給前端控制器?
2、 前端控制器如何根據(jù)請(qǐng)求信息選擇頁面控制器進(jìn)行功能處理?
3、 如何支持多種頁面控制器呢?
4、 如何頁面控制器如何使用業(yè)務(wù)對(duì)象?
5、 頁面控制器如何返回模型數(shù)據(jù)?
6、 前端控制器如何根據(jù)頁面控制器返回的邏輯視圖名選擇具體的視圖進(jìn)行渲染?
7、 不同的視圖技術(shù)如何使用相應(yīng)的模型數(shù)據(jù)?
首先我們知道有如上問題,那這些問題如何解決呢?請(qǐng)讓我們先繼續(xù),在后邊依次回答。
1、Spring Web MVC核心架構(gòu)圖,如圖2-2
圖2-2
架構(gòu)圖對(duì)應(yīng)的DispatcherServlet核心代碼如下:
java代碼:
//前端控制器分派方法 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; int interceptorIndex = -1; try { ModelAndView mv; boolean errorView = false; try { //檢查是否是請(qǐng)求是否是multipart(如文件上傳),如果是將通過MultipartResolver解析 processedRequest = checkMultipart(request); //步驟2、請(qǐng)求到處理器(頁面控制器)的映射,通過HandlerMapping進(jìn)行映射 mappedHandler = getHandler(processedRequest, false); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } //步驟3、處理器適配,即將我們的處理器包裝成相應(yīng)的適配器(從而支持多種類型的處理器) HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 304 Not Modified緩存支持 //此處省略具體代碼 // 執(zhí)行處理器相關(guān)的攔截器的預(yù)處理(HandlerInterceptor.preHandle) //此處省略具體代碼 // 步驟4、由適配器執(zhí)行處理器(調(diào)用處理器相應(yīng)功能處理方法) mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // Do we need view name translation? if (mv != null && !mv.hasView()) { mv.setViewName(getDefaultViewName(request)); } // 執(zhí)行處理器相關(guān)的攔截器的后處理(HandlerInterceptor.postHandle) //此處省略具體代碼 } catch (ModelAndViewDefiningException ex) { logger.debug("ModelAndViewDefiningException encountered", ex); mv = ex.getModelAndView(); } catch (Exception ex) { Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); mv = processHandlerException(processedRequest, response, handler, ex); errorView = (mv != null); } //步驟5 步驟6、解析視圖并進(jìn)行視圖的渲染 //步驟5 由ViewResolver解析View(viewResolver.resolveViewName(viewName, locale)) //步驟6 視圖在渲染時(shí)會(huì)把Model傳入(view.render(mv.getModelInternal(), request, response);) if (mv != null && !mv.wasCleared()) { render(mv, processedRequest, response); if (errorView) { WebUtils.clearErrorRequestAttributes(request); } } else { if (logger.isDebugEnabled()) { logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() + "': assuming HandlerAdapter completed request handling"); } } // 執(zhí)行處理器相關(guān)的攔截器的完成后處理(HandlerInterceptor.afterCompletion) //此處省略具體代碼 catch (Exception ex) { // Trigger after-completion for thrown exception. triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex); throw ex; } catch (Error err) { ServletException ex = new NestedServletException("Handler processing failed", err); // Trigger after-completion for thrown exception. triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex); throw ex; } finally { // Clean up any resources used by a multipart request. if (processedRequest != request) { cleanupMultipart(processedRequest); } } }
核心架構(gòu)的具體流程步驟如下:
1、 首先用戶發(fā)送請(qǐng)求——>DispatcherServlet,前端控制器收到請(qǐng)求后自己不進(jìn)行處理,而是委托給其他的解析器進(jìn)行處理,作為統(tǒng)一訪問點(diǎn),進(jìn)行全局的流程控制;
2、 DispatcherServlet——>HandlerMapping, HandlerMapping將會(huì)把請(qǐng)求映射為HandlerExecutionChain對(duì)象(包含一個(gè)Handler處理器(頁面控制器)對(duì)象、多個(gè)HandlerInterceptor攔截器)對(duì)象,通過這種策略模式,很容易添加新的映射策略;
3、 DispatcherServlet——>HandlerAdapter,HandlerAdapter將會(huì)把處理器包裝為適配器,從而支持多種類型的處理器,即適配器設(shè)計(jì)模式的應(yīng)用,從而很容易支持很多類型的處理器;
4、 HandlerAdapter——>處理器功能處理方法的調(diào)用,HandlerAdapter將會(huì)根據(jù)適配的結(jié)果調(diào)用真正的處理器的功能處理方法,完成功能處理;并返回一個(gè)ModelAndView對(duì)象(包含模型數(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é)束。
此處我們只是講了核心流程,沒有考慮攔截器、本地解析、文件上傳解析等,后邊再細(xì)述。
到此,再來看我們前邊提出的問題:
1、 請(qǐng)求如何給前端控制器?這個(gè)應(yīng)該在web.xml中進(jìn)行部署描述,在HelloWorld中詳細(xì)講解。
2、 前端控制器如何根據(jù)請(qǐng)求信息選擇頁面控制器進(jìn)行功能處理? 我們需要配置HandlerMapping進(jìn)行映射
3、 如何支持多種頁面控制器呢?配置HandlerAdapter從而支持多種類型的頁面控制器
4、 如何頁面控制器如何使用業(yè)務(wù)對(duì)象?可以預(yù)料到,肯定利用Spring IoC容器的依賴注入功能
5、 頁面控制器如何返回模型數(shù)據(jù)?使用ModelAndView返回
6、 前端控制器如何根據(jù)頁面控制器返回的邏輯視圖名選擇具體的視圖進(jìn)行渲染? 使用ViewResolver進(jìn)行解析
7、 不同的視圖技術(shù)如何使用相應(yīng)的模型數(shù)據(jù)? 因?yàn)镸odel是一個(gè)Map數(shù)據(jù)結(jié)構(gòu),很容易支持其他視圖技術(shù)
在此我們可以看出具體的核心開發(fā)步驟:
1、 DispatcherServlet在web.xml中的部署描述,從而攔截請(qǐng)求到Spring Web MVC
2、 HandlerMapping的配置,從而將請(qǐng)求映射到處理器
3、 HandlerAdapter的配置,從而支持多種類型的處理器
4、 ViewResolver的配置,從而將邏輯視圖名解析為具體視圖技術(shù)
5、處理器(頁面控制器)的配置,從而進(jìn)行功能處理
上邊的開發(fā)步驟我們會(huì)在Hello World中詳細(xì)驗(yàn)證。
1、清晰的角色劃分:前端控制器(DispatcherServlet
)、請(qǐng)求到處理器映射(HandlerMapping)、處理器適配器(HandlerAdapter)、視圖解析器(ViewResolver)、處理器或頁面控制器(Controller)、驗(yàn)證器( Validator)、命令對(duì)象(Command 請(qǐng)求參數(shù)綁定到的對(duì)象就叫命令對(duì)象)、表單對(duì)象(Form Object 提供給表單展示和提交到的對(duì)象就叫表單對(duì)象)。
2、分工明確,而且擴(kuò)展點(diǎn)相當(dāng)靈活,可以很容易擴(kuò)展,雖然幾乎不需要;
3、由于命令對(duì)象就是一個(gè)POJO,無需繼承框架特定API,可以使用命令對(duì)象直接作為業(yè)務(wù)對(duì)象;
4、和Spring 其他框架無縫集成,是其它Web框架所不具備的;
5、可適配,通過HandlerAdapter可以支持任意的類作為處理器;
6、可定制性,HandlerMapping、ViewResolver等能夠非常簡單的定制;
7、功能強(qiáng)大的數(shù)據(jù)驗(yàn)證、格式化、綁定機(jī)制;
8、利用Spring提供的Mock對(duì)象能夠非常簡單的進(jìn)行Web層單元測(cè)試;
9、本地化、主題的解析的支持,使我們更容易進(jìn)行國際化和主題的切換。
10、強(qiáng)大的JSP標(biāo)簽庫,使JSP編寫更容易。
………………還有比如RESTful風(fēng)格的支持、簡單的文件上傳、約定大于配置的契約式編程支持、基于注解的零配置支持等等。
DispatcherServlet是前端控制器設(shè)計(jì)模式的實(shí)現(xiàn),提供Spring Web MVC的集中訪問點(diǎn),而且負(fù)責(zé)職責(zé)的分派,而且與Spring IoC容器無縫集成,從而可以獲得Spring的所有好處。 具體請(qǐng)參考第二章的圖2-1。
DispatcherServlet主要用作職責(zé)調(diào)度工作,本身主要用于控制流程,主要職責(zé)如下:
1、文件上傳解析,如果請(qǐng)求類型是multipart將通過MultipartResolver進(jìn)行文件上傳解析;
2、通過HandlerMapping,將請(qǐng)求映射到處理器(返回一個(gè)HandlerExecutionChain,它包括一個(gè)處理器、多個(gè)HandlerInterceptor攔截器);
3、通過HandlerAdapter支持多種類型的處理器(HandlerExecutionChain中的處理器);
4、通過ViewResolver解析邏輯視圖名到具體視圖實(shí)現(xiàn);
5、本地化解析;
6、渲染具體的視圖等;
7、如果執(zhí)行過程中遇到異常將交給HandlerExceptionResolver來解析。
從以上我們可以看出DispatcherServlet主要負(fù)責(zé)流程的控制(而且在流程中的每個(gè)關(guān)鍵點(diǎn)都是很容易擴(kuò)展的)。
以上是“SpringMVC如何實(shí)現(xiàn)”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道!
分享標(biāo)題:SpringMVC如何實(shí)現(xiàn)-創(chuàng)新互聯(lián)
文章位置:http://jinyejixie.com/article46/dijheg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、微信公眾號(hào)、網(wǎng)頁設(shè)計(jì)公司、品牌網(wǎng)站建設(shè)、App設(shè)計(jì)、標(biāo)簽優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容