真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

SpringMVC的處理流程是什么

本篇內(nèi)容介紹了“Spring MVC的處理流程是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)是專業(yè)的撫州網(wǎng)站建設(shè)公司,撫州接單;提供成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、成都外貿(mào)網(wǎng)站建設(shè)公司,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行撫州網(wǎng)站開發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!

Spring MVC的處理流程是什么

1、曾經(jīng)的王者——Servlet

在筆者剛接觸到使用Java進(jìn)行Web開發(fā)的時(shí)候,Spring MVC遠(yuǎn)沒有今天這么流行,君不見曾經(jīng)的王者Servlet繁盛一時(shí)的場(chǎng)面?,F(xiàn)在回想起來(lái),使用Servlet進(jìn)行開發(fā)雖然不像現(xiàn)在這么容易,好多的事情需要自己做,但是Servlet使得開發(fā)的邏輯變得十分清晰,尤其是在Servlet與jsp很好的承擔(dān)了各自的角色之后,再加上mvc分層思想的流行。編寫Web應(yīng)用程序在那時(shí)是一件快樂(lè)而又簡(jiǎn)單的事情。

實(shí)際上Servlet做的事情并不是很多,筆者覺得Servlet想要完成的就是統(tǒng)一請(qǐng)求的接受、處理與響應(yīng)的流程。

網(wǎng)絡(luò)編程中繞不開的一個(gè)東東想必不用說(shuō)大家也猜得到,那就是Socket。但是網(wǎng)絡(luò)需要傳輸?shù)脑捠呛軓?fù)雜的,首先需要遵循一定的協(xié)議,現(xiàn)在我們一般使用Http與Https傳輸數(shù)據(jù),而Socket就是在一些網(wǎng)絡(luò)協(xié)議之上,屏蔽了底層協(xié)議的細(xì)節(jié),為使用者提供一個(gè)統(tǒng)一的api。但是Servlet認(rèn)為Socket做的還不夠,或者說(shuō)我們還要進(jìn)行相應(yīng)的處理。于是Servlet(就HttpServlet來(lái)說(shuō)),他將網(wǎng)絡(luò)中的請(qǐng)求報(bào)文進(jìn)行封裝轉(zhuǎn)化成為了Request表示,在Http通信過(guò)程之中就是HttpServletRequest,而將服務(wù)端處理請(qǐng)求后返回的響應(yīng)統(tǒng)一的封裝為了HttpServletResponse對(duì)象。

這樣做的好處是什么呢?

我們作為開發(fā)者,不必再去做一些處理網(wǎng)絡(luò)請(qǐng)求與響應(yīng)的繁瑣之事,而只需要關(guān)注于我們的業(yè)務(wù)邏輯開發(fā)。

大家有沒有發(fā)現(xiàn),每一次框架效率的提升很多時(shí)候都是在將最最重要的業(yè)務(wù)邏輯與其他任務(wù)盡可能完全的分離開,使我們總可以全身心的投入到業(yè)務(wù)邏輯的開發(fā)之中,Spring AOP是不是就是一個(gè)很好的佐證呢!

那么Servlet如何使用呢?

沒有Servlet使用經(jīng)歷的同學(xué)可以聽我簡(jiǎn)單的說(shuō)一說(shuō):

 1.  首先我們通常要編寫一個(gè)自己的Servlet然后繼承自HttpServlet,然后重寫其doGet()與doPost()方法。這兩個(gè)方法都會(huì)將HttpServletRequest與HttpServletResponse作為參數(shù)傳遞進(jìn)去,然后我們從Request中提取前端傳來(lái)的參數(shù),在相應(yīng)的doXXX方法內(nèi)調(diào)用事先編寫好的Service接口,Dao接口即可將數(shù)據(jù)準(zhǔn)備好放置到Response中并跳轉(zhuǎn)到指定的頁(yè)面即可,跳轉(zhuǎn)的方式可以選擇轉(zhuǎn)發(fā)或者重定向。

2.  Servlet使用的是模板方法的設(shè)計(jì)模式,在Servlet頂層將會(huì)調(diào)用service方法,該方法會(huì)構(gòu)造HttpServletRequest與HttpServletResponse對(duì)象作為參數(shù)調(diào)用子類重寫的doXXX()方法。然后返回請(qǐng)求。

3.  最后我們需要將我們編寫的自定義Servlet注冊(cè)到web.xml中,在web.xml中配置servlet-mapping來(lái)為該servlet指定處理哪些請(qǐng)求。

Servlet的使用就是這么簡(jiǎn)單!事實(shí)上,在很長(zhǎng)的一段時(shí)間內(nèi)他的流行也得益于他的簡(jiǎn)單易用易上手。

                    ShoppingServlet              com.myTest.ShoppingServlet                          ShoppingServlet              /shop/ShoppingServlet        

2、想要更進(jìn)一步

當(dāng)我們使用Servlet來(lái)進(jìn)行業(yè)務(wù)邏輯開發(fā)的時(shí)候,時(shí)常會(huì)感覺到爽歪歪,但是爽歪歪的同時(shí)也感覺到有那么一點(diǎn)點(diǎn)不適。不適的地方主要有以下幾點(diǎn):

  •  每個(gè)Servlet只能處理一個(gè)請(qǐng)求,這樣當(dāng)系統(tǒng)比較大,業(yè)務(wù)比較復(fù)雜的時(shí)候可能會(huì)存在成百上千的Servlet,找起來(lái)都眼花。

  •  每次我們都需要手動(dòng)的從Request中獲取請(qǐng)求參數(shù),然后封裝成我們想要的對(duì)象,這其中可能還要對(duì)參數(shù)進(jìn)行校驗(yàn),在調(diào)用業(yè)務(wù)邏輯層獲取到數(shù)據(jù)之后,我們還要手動(dòng)的設(shè)置到響應(yīng)中,同時(shí)手動(dòng)的選擇轉(zhuǎn)發(fā)或者重定向進(jìn)行跳轉(zhuǎn)。

  •  我們的請(qǐng)求的url是硬配置到web.xml中的,缺乏靈活性,如果可以動(dòng)態(tài)的配置這種請(qǐng)求url與處理的對(duì)應(yīng)關(guān)系就好了。

  •  我們的Servlet與前端的渲染框架緊耦合在一塊,這樣當(dāng)前端換一種顯示技術(shù)的時(shí)候就需要改動(dòng)較大的代碼,如果能把數(shù)據(jù)的處理與數(shù)據(jù)的顯示分離,讓其松散耦合就更好了。

帶著這些思考,能不能進(jìn)一步的來(lái)抽離業(yè)務(wù)邏輯的開發(fā)呢?

在早期的時(shí)候筆者也曾進(jìn)行一些嘗試,其大概思路就是編寫一個(gè)BaseServlet,然后我們自己定義的Servlet繼承自BaseServlet,前端的請(qǐng)求需要指定Servlet的哪個(gè)方法進(jìn)行處理,這樣請(qǐng)求的時(shí)候?qū)⑿枰獛弦粋€(gè)method參數(shù),例如這樣:

http://localhost:8080/myProject/MyServlet?method=getInfo

在BaseServlet中將提取該參數(shù)信息,并使用反射的方法調(diào)用子類的該方法,子類方法統(tǒng)一返回String類型的結(jié)果,代表要返回的邏輯視圖名,也就是要跳轉(zhuǎn)的路徑,然后父類拿到結(jié)果,使用重定向或者轉(zhuǎn)發(fā)進(jìn)行跳轉(zhuǎn)。

說(shuō)到這里,有小伙伴肯定不耐煩了,明明是講Spring MVC的,到現(xiàn)在連個(gè)Spring MVC的影都還沒見,全是在講Servlet。先別著急,理解這些對(duì)我們理解Spring MVC有很大的幫助,請(qǐng)往下看

說(shuō)到這里,其實(shí)是想說(shuō),如果我們想要在Servlet上更進(jìn)一步,想要進(jìn)一步的將業(yè)務(wù)邏輯與其他工作相分離,那么就需要在Servlet之上,構(gòu)建一個(gè)事無(wú)巨細(xì),任勞任怨,神通過(guò)大,...(額想不起來(lái)。。。)的超級(jí)Servlet,來(lái)為我們做這些工作,我們暫且把這個(gè)Servlet叫做超級(jí)牛逼Servlet。而開發(fā)Spring的那些人是啥大佬,我們能想到這些,他們能想不到?于是他們動(dòng)手開發(fā)了這個(gè)超級(jí)牛逼Servlet,并正式命名為DispatcherServlet。

3、Spring MVC——兩級(jí)控制器方式

接下來(lái)我們就要正式的開始Spring MVC之旅了,通過(guò)前面的了解,我們知道Spring MVC把那個(gè)超級(jí)牛逼Servlet叫做DispatcherServlet,這個(gè)Servlet可以說(shuō)為簡(jiǎn)化我們的開發(fā)操碎了心,我們稱之為_前端控制器?,F(xiàn)在我們不禁思考,前面我們寫的BaseServlet對(duì)應(yīng)現(xiàn)在的超級(jí)牛逼Servlet(DispatcherServlet)。那么定義我們業(yè)務(wù)邏輯的自定義Servlet叫啥呢?Spring MVC管定義我們的業(yè)務(wù)邏輯處理的類叫做Handler,只不過(guò)他不再是一個(gè)Servlet了,而是一個(gè)普普通通的類,這也很好理解,畢竟DispatcherServlet做了太多,而且那么牛逼,完全可以像對(duì)待Servlet一樣對(duì)待一個(gè)普通的類,而這個(gè)Handler就叫做次級(jí)控制器_。

這里可能有小伙伴持反對(duì)意見了,有的書上說(shuō)了Spring MVC的次級(jí)控制器叫Controller,不是Handler。

其實(shí)Spring MVC的次級(jí)控制器確實(shí)是叫Handler,只不過(guò)Hander是一個(gè)抽象的,而Spring MVC選擇使用Controller來(lái)實(shí)現(xiàn)Handler,講到這里,你覺得我們能不能自定義一個(gè)Handler實(shí)現(xiàn),叫做Lellortnoc呢?答案當(dāng)然是可以的!就好像List是一個(gè)抽象的接口,而List的實(shí)現(xiàn)有ArrayList,LinkedList一樣。

4、DispatcherServlet——前端控制器

DispatcherServlet是整個(gè)Spring MVC的核心,超級(jí)牛逼Servlet這個(gè)榮譽(yù)稱號(hào)他是名副其實(shí)。DispatcherServlet和其家族成員兄弟一起完成了很多的工作,包括請(qǐng)求參數(shù)的自動(dòng)綁定,參數(shù)的自動(dòng)校驗(yàn),請(qǐng)求url的自動(dòng)匹配,邏輯視圖名到真實(shí)頁(yè)面的跳轉(zhuǎn),數(shù)據(jù)獲取與數(shù)據(jù)渲染顯示的分離等等。。。在此過(guò)程中他更像是一個(gè)指揮家,有條不紊的指揮著請(qǐng)求不斷的向前處理,并最終完成服務(wù)端的響應(yīng)數(shù)據(jù)。

想要了解具體DispatcherServlet都是怎么指揮的,那就繼續(xù)往下看吧!推薦:250期面試題匯總

5、HandlerMapper——請(qǐng)求映射專家

想想我們?cè)谑褂肧ervlet編寫代碼的時(shí)候,請(qǐng)求的映射工作是交給了web.xml。但是現(xiàn)在Spring MVC采用了兩級(jí)控制器的方式,就必須解決這個(gè)棘手的問(wèn)題。

首先DispatcherServlet也是一個(gè)Servlet,那么我們也應(yīng)該在web.xml中配置其處理的請(qǐng)求路徑。那么應(yīng)該配置什么路徑呢?我們說(shuō)DispatcherServlet被稱為超級(jí)牛逼Serlvet,我們希望它能處理所有的請(qǐng)求,那么就可以讓DispatcherServlet接受所有請(qǐng)求的處理。像下面這樣配置:

                 Spring MVC            org.springframework.web.servlet.DispatcherServlet                                        contextConfigLocation                classpath:Spring-servlet.xml                        1                          Spring MVC            /*         

現(xiàn)在所有的請(qǐng)求都被映射到了DispatcherServlet,那么DispatcherServlet現(xiàn)在就有責(zé)任將請(qǐng)求分發(fā)至具體的次級(jí)控制器,如何找到或者說(shuō)如何保存請(qǐng)求到具體的次級(jí)控制器的這種映射關(guān)系呢?DispatcherServlet選擇請(qǐng)求他的好兄弟HandlerMapping。

在HandlerMapping中,保存了特定的請(qǐng)求url應(yīng)該被哪一個(gè)Handler(也就是通常的Controller)所處理。HandlerMapping根據(jù)映射策略的不同,大概有下面幾種映射查找方式:

  1. 鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)

  2.  org.springframework.web.servlet.handler.SimpleUrlHandlerMapping 通過(guò)配置請(qǐng)求路徑和Controller映射建立關(guān)系,找到相應(yīng)的Controller

  3.  org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping 通過(guò) Controller 的類名找到請(qǐng)求的Controller。

  4.  org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping 通過(guò)定義的 beanName 進(jìn)行查找要請(qǐng)求的Controller

  5.  org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping 通過(guò)注解 @RequestMapping(“/userlist”) 來(lái)查找對(duì)應(yīng)的Controller。

想必現(xiàn)在最常用的就是第四種了吧,直接在對(duì)應(yīng)的Controller上以及其內(nèi)部的方法之上加上相應(yīng)的注解,就可以配置好請(qǐng)求的映射,簡(jiǎn)直是香香的。推薦:250期面試題匯總

6、Handler的攔路虎——HandlerInterceptor

聊到這里,你以為DispatcherServlet把請(qǐng)求的url交給HandlerMapping, HandlerMapping根據(jù)請(qǐng)求查出對(duì)應(yīng)的Controller來(lái)交給DispatcherServlet, 然后DispatcherServlet交給Controller執(zhí)行就完事了?那就To young to native了,這其中還有一些小插曲。比如我們不能啥請(qǐng)求不管三七二十一都交給Handler執(zhí)行吧,最起碼要過(guò)濾一下不合理的請(qǐng)求,比如跳轉(zhuǎn)頁(yè)面的時(shí)候檢查Session,如果用戶沒登錄跳轉(zhuǎn)到登錄界面啊,以及一些程序的異常以統(tǒng)一的方式跳轉(zhuǎn)等等,都需要對(duì)請(qǐng)求進(jìn)行攔截。

如果對(duì)Servlet了解的同學(xué)是不是有一點(diǎn)似曾相識(shí)的感覺?沒錯(cuò),Servlet中的Filter也可以完成請(qǐng)求攔截與過(guò)濾的功能,不過(guò)既然Spring MVC是兩級(jí)控制器結(jié)構(gòu),那么HandlerInterceptor就與Filter有一些細(xì)微的差別,其最主要的差別,筆者認(rèn)為HandlerInterceptor提供了更細(xì)粒度的攔截。畢竟Filter攔截的對(duì)象是Serlvet,而HandlerInterceptor攔截的則是Handler(Controller)。用一張圖可以生動(dòng)的表現(xiàn)出來(lái)。

Spring MVC的處理流程是什么

HandlerInterceptor.jpg

從圖中我們可以看出HandlerInteceptor可以配置多個(gè),其中任何一個(gè)返回false的話,請(qǐng)求都將被攔截,直接返回。

7、次級(jí)控制器——Handler

前端控制器我們已經(jīng)很熟悉了,而次級(jí)控制器也就是Handler,是我們真正執(zhí)行業(yè)務(wù)邏輯的類。通常在Spring MVC中,這個(gè)Handler就是我們很熟悉的Controller。我們調(diào)用封裝好的業(yè)務(wù)邏輯接口就是在這里進(jìn)行處理的??梢哉f(shuō)Spring MVC已經(jīng)將業(yè)務(wù)邏輯與其他不相關(guān)的繁雜工作分離的較為徹底了。這樣,我們就在Handler(Controller)中專心的編寫我們的業(yè)務(wù)邏輯吧!

8、Handler與HandlerInterceptor的橋梁——HandlerExecutionChain

前面講到DispatherServlet求助HandlerMapping進(jìn)行url與次級(jí)控制器的映射,但是DispatherServlet在將url交給特定的HandlerMapping之后,HandlerMapping在進(jìn)行了一頓猛如虎的操作之后,返回給DispaterServlet的卻不是一個(gè)可執(zhí)行的Handler(Controller),而是一個(gè)HandlerExecutionChain對(duì)象。那么HandlerMapping究竟為什么要返回給這樣的一個(gè)對(duì)象而不是返回Handler對(duì)象呢?

其實(shí)在看上面圖的時(shí)候,你有沒有納悶,HandlerInterceptor與Handler是怎樣聯(lián)系在一起的呢?答案就是HandlerExecutionChain。它就是若干的HandlerInterceptor與Handler的組合。那么是怎么組合的呢?

這里就涉及到設(shè)計(jì)模式中的責(zé)任鏈設(shè)計(jì)模式,HandlerExecutionChain將HandlerInterceptor與Handler串成一個(gè)執(zhí)行鏈的形式,首先請(qǐng)求會(huì)被第一個(gè)HandlerInterceptor攔截,如果返回false,那么直接短路請(qǐng)求,如果返回true,那么再交給第二個(gè)HandlerInterceptor處理,直到所有的HandlerInterceptor都檢查通過(guò),請(qǐng)求才到達(dá)Handler(Controller),交由Handler正式的處理請(qǐng)求。執(zhí)行完成之后再逐層的返回。

而DispatcherServlet拿到的就是這樣一個(gè)串聯(lián)好的HandlerExecutionChain,然后順序的執(zhí)行請(qǐng)求。

9、解耦的關(guān)鍵——ModelAndView

到這里,請(qǐng)求終于來(lái)到了對(duì)應(yīng)的Handler。我們希望的是Handler只處理負(fù)責(zé)的業(yè)務(wù)邏輯即可,而一些url的跳轉(zhuǎn)等無(wú)需Handler負(fù)責(zé)。那么DispatcherServlet就使用了ModelAndView保存我們的數(shù)據(jù)和想要跳轉(zhuǎn)的路徑。

我們調(diào)用業(yè)務(wù)邏輯層獲取數(shù)據(jù),并將數(shù)據(jù)封裝到ModelAndView中,同時(shí)設(shè)置ModelAndView的view邏輯視圖名稱。從ModelAndView的名稱可以看出,它保存了Handler執(zhí)行完成之后所需要發(fā)送到前端的數(shù)據(jù),以及需要跳轉(zhuǎn)的路徑。這些是DispatcherServlet需要用到的。推薦:250期面試題匯總

10、視圖渲染查找——ViewResolver

這一步是Spring MVC將數(shù)據(jù)的獲取與數(shù)據(jù)的顯示渲染相分離的關(guān)鍵,前端可能采用各種各樣的方式顯示數(shù)據(jù),可能是Jsp,可能是Html,也可能是其他的方式。DispatcherServlet已經(jīng)拿到了ModelAndView,這里面有執(zhí)行完成請(qǐng)求后返回的響應(yīng)結(jié)果數(shù)據(jù),還有邏輯視圖的路徑,這個(gè)時(shí)候DispatcherServlet就需要根據(jù)這個(gè)邏輯視圖的路徑去查找誰(shuí)能把數(shù)據(jù)進(jìn)行解析與渲染。

比如說(shuō)我們使用FreeMarker模板引擎渲染數(shù)據(jù),那么這個(gè)時(shí)候就要找到能夠勝任該工作的那個(gè)View實(shí)現(xiàn)類,那么問(wèn)題來(lái)了,如何尋找呢?以什么策略尋找呢?這個(gè)就依賴我們的ViewResolver了。

通常的尋找策略有以下幾種:

  •  BeanNameViewResolver :將邏輯視圖名解析為一個(gè)Bean,Bean的id等于邏輯視圖名。

  •  XmlViewResolver:和BeanNameViewResolver類似,只不過(guò)目標(biāo)視圖Bean對(duì)象定義在一個(gè)獨(dú)立的XML文件中,而非定義在DispatcherServlet上下文的主配置文件中

  •  InternalResourceViewResovlver:將視圖名解析為一個(gè)URL文件,一般使用該解析器將視圖名映射為保存在WEB-INF目錄中的程序文件(如JSP)

  •  XsltViewResolver:將視圖名解析為一個(gè)指定XSLT樣式表的URL文件

  •  JasperReportsViewResolver:JasperReports是一個(gè)基于java的開源報(bào)表工具,該解析器將視圖名解析為報(bào)表文件對(duì)應(yīng)的URL

  •  FreeMarkerViewResolver:解析為基于FreeMarker模板技術(shù)的模板文件

  •  VelocityViewResolver和VelocityLayoutViewResolver:解析為基于Velocity模板技術(shù)的模板文件

11、數(shù)據(jù)渲染——View

在根據(jù)邏輯視圖名借助ViewResolver查找到對(duì)應(yīng)的View實(shí)現(xiàn)類之后,DispatcherServlet就會(huì)將ModelAndView中的數(shù)據(jù)交給View實(shí)現(xiàn)類來(lái)進(jìn)行渲染,待該View渲染完成之后,會(huì)將渲染完成的數(shù)據(jù)交給DispatcherServlet,這時(shí)候DispatcherServlet將其封裝到Response返回給前端顯示。

至此,整個(gè)Spring MVC的處理流程就算完成了,當(dāng)然這其中還會(huì)有對(duì)于國(guó)際化的支持,主題的定義與設(shè)置等等,但是這些是不常用的,Spring MVC最主要的處理流程所需要的用到的就是以上這些類。可以看到在此過(guò)程中,DispatcherServlet起到了至關(guān)重要的作用,所以說(shuō)Spring MVC的核心就在于DispatcherServlet。

最后附上一張流程圖作為以上內(nèi)容的總結(jié)。

Spring MVC的處理流程是什么

“Spring MVC的處理流程是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


本文名稱:SpringMVC的處理流程是什么
分享路徑:http://weahome.cn/article/jscddi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部