日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

springMVC 的工作原理和机制

發(fā)布時(shí)間:2024/2/28 c/c++ 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 springMVC 的工作原理和机制 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)載自?https://www.cnblogs.com/zbf1214/p/5265117.html

?


工作原理
上面的是springMVC的工作原理圖:

1、客戶端發(fā)出一個(gè)http請求給web服務(wù)器,web服務(wù)器對http請求進(jìn)行解析,如果匹配DispatcherServlet的請求映射路徑(在web.xml中指定),web容器將請求轉(zhuǎn)交給DispatcherServlet.

2、DipatcherServlet接收到這個(gè)請求之后將根據(jù)請求的信息(包括URL、Http方法、請求報(bào)文頭和請求參數(shù)Cookie等)以及HandlerMapping的配置找到處理請求的處理器(Handler)。

3-4、DispatcherServlet根據(jù)HandlerMapping找到對應(yīng)的Handler,將處理權(quán)交給Handler(Handler將具體的處理進(jìn)行封裝),再由具體的HandlerAdapter對Handler進(jìn)行具體的調(diào)用。

5、Handler對數(shù)據(jù)處理完成以后將返回一個(gè)ModelAndView()對象給DispatcherServlet。

6、Handler返回的ModelAndView()只是一個(gè)邏輯視圖并不是一個(gè)正式的視圖,DispatcherSevlet通過ViewResolver將邏輯視圖轉(zhuǎn)化為真正的視圖View。

7、Dispatcher通過model解析出ModelAndView()中的參數(shù)進(jìn)行解析最終展現(xiàn)出完整的view并返回給客戶端。

?

工作機(jī)制是什么

Control的調(diào)用(續(xù))

接著對于(二)的補(bǔ)充:主要是小結(jié)下Control的處理邏輯的關(guān)鍵操作;

對于control的處理關(guān)鍵就是:DispatcherServlet的handlerMappings集合中根據(jù)請求的URL匹配每一個(gè)handlerMapping對象中的某個(gè)handler,匹配成功之后將會(huì)返回這個(gè)handler的處理連接handlerExecutionChain對象。而這個(gè)handlerExecutionChain對象中將會(huì)包含用戶自定義的多個(gè)handlerInterceptor對象。

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 /** ?????* Return the HandlerExecutionChain for this request. ?????* <p>Tries all handler mappings in order. ?????* @param request current HTTP request ?????* @return the HandlerExecutionChain, or <code>null</code> if no handler could be found ?????*/ ????protected?HandlerExecutionChain getHandler(HttpServletRequest request) throws?Exception { ????????for?(HandlerMapping hm : this.handlerMappings) { ????????????if?(logger.isTraceEnabled()) { ????????????????logger.trace( ????????????????????????"Testing handler map ["?+ hm + "] in DispatcherServlet with name '"?+ getServletName() + "'"); ????????????} ????????????HandlerExecutionChain handler = hm.getHandler(request); ????????????if?(handler != null) { ????????????????return?handler; ????????????} ????????} ????????return?null; ????}

而對于handlerInterceptor接口中定義的三個(gè)方法中,preHandler和postHandler分別在handler的執(zhí)行前和執(zhí)行后執(zhí)行,afterCompletion在view渲染完成、在DispatcherServlet返回之前執(zhí)行。

?

PS:這么我們需要注意的是:當(dāng)preHandler返回false時(shí),當(dāng)前的請求將在執(zhí)行完afterCompletion后直接返回,handler也將不會(huì)執(zhí)行。

在類HandlerExecutionChain中的getHandler()方法是返回object對象的;

?

1 2 3 4 5 6 7 /** ?????* Return the handler object to execute. ?????* @return the handler object ?????*/ ????public?Object getHandler() { ????????return?this.handler; ????}

這里的handler是沒有類型的,handler的類型是由handlerAdapter決定的。dispatcherServlet會(huì)根據(jù)handler對象在其handlerAdapters集合中匹配哪個(gè)HandlerAdapter實(shí)例支持該對象。接下來去執(zhí)行handler對象的相應(yīng)方法了,如果該handler對象的相應(yīng)方法返回一個(gè)ModelAndView對象接下來就是去執(zhí)行View渲染了。

?

?

1 2 3 4 5 6 7 /** ?????* Return the handler object to execute. ?????* @return the handler object ?????*/ ????public?Object getHandler() { ????????return?this.handler; ????}

?

---------------------------------------邪惡的分割線---------------------------------------------

Model設(shè)計(jì)

如果handler兌現(xiàn)返回了ModelAndView對象,那么說明Handler需要傳一個(gè)Model實(shí)例給view去渲染模版。除了渲染頁面需要model實(shí)例,在業(yè)務(wù)邏輯層通常也有Model實(shí)例。

?

ModelAndView對象是連接業(yè)務(wù)邏輯層與view展示層的橋梁,對spring MVC來說它也是連接Handler與view的橋梁。ModelAndView對象顧名思義會(huì)持有一個(gè)ModelMap對象和一個(gè)View對象或者View的名稱。ModelMap對象就是執(zhí)行模版渲染時(shí)候所需要的變量對應(yīng)的實(shí)例,如jsp的通過request.getAttribute(String)獲取的JSTL標(biāo)簽名對應(yīng)的對象。velocity中context.get(String)獲取$foo對應(yīng)的變量實(shí)例。

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 public?class?ModelAndView { /** View instance or view name String */ ????private?Object view; ????/** Model Map */ ????private?ModelMap model; ????/** Indicates whether or not this instance has been cleared with a call to {@link #clear()} */ ????private?boolean?cleared = false; ..... }

?

ModelMap其實(shí)也是一個(gè)Map,Handler中將模版中需要的對象存在這個(gè)Map中,然后傳遞到view對應(yīng)的ViewResolver中。

?

1 2 3 4 public?interface?ViewResolver { ????View resolveViewName(String viewName, Locale locale) throws?Exception; }

?

不同的ViewResolver會(huì)對這個(gè)Map中的對象有不同的處理方式;

?

  • velocity中將這個(gè)Map保存到VelocityContext中。
  • JSP中將每一個(gè)ModelMap中的元素分別設(shè)置到request.setAttribute(modelName,modelValue);

-----------------------邪惡的分割線-----------------------------------------------

view設(shè)計(jì)

在spring MVC中,view模塊需要兩個(gè)組件來支持:RequestToViewNameTranslator和ViewResolver

?

1 2 3 4 5 6 7 8 9 10 11 12 public?interface?RequestToViewNameTranslator { ????/** ?????* Translate the given {@link HttpServletRequest} into a view name. ?????* @param request the incoming {@link HttpServletRequest} providing ?????* the context from which a view name is to be resolved ?????* @return the view name (or <code>null</code> if no default found) ?????* @throws Exception if view name translation fails ?????*/ ????String getViewName(HttpServletRequest request) throws?Exception; }

對于?ViewResolver,前面有寫到了,就不寫了;

?

-----------------------邪惡的分割線-------------------------------------------------

RequestToViewNameTranslator:主要支持用戶自定義對viewName的解析,如將請求的ViewName加上前綴或者后綴,或者替換成特定的字符串等。

ViewResolver:主要是根據(jù)用戶請求的viewName創(chuàng)建適合的模版引擎來渲染最終的頁面,ViewResolver會(huì)根據(jù)viewName創(chuàng)建一個(gè)view對象,調(diào)用view對象的Void render方法渲染出頁面;

?

1 2 3 public?interface?View { void?render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws?Exception; }

下面來總結(jié)下 Spring MVC解析View的邏輯:

?

?

  • dispatcherServlet方法調(diào)用getDefaultViewName()方法;

?

?

1 2 3 4 5 6 7 8 9 /** ?????* Translate the supplied request into a default view name. ?????* @param request current HTTP servlet request ?????* @return the view name (or <code>null</code> if no default found) ?????* @throws Exception if view name translation failed ?????*/ ????protected?String getDefaultViewName(HttpServletRequest request) throws?Exception { ????????return?this.viewNameTranslator.getViewName(request); ????}
  • 調(diào)用了RequestToViewNameTranslator的getViewName方法;

?

1 2 3 4 5 6 7 8 9 10 11 12 public?interface?RequestToViewNameTranslator { ????/** ?????* Translate the given {@link HttpServletRequest} into a view name. ?????* @param request the incoming {@link HttpServletRequest} providing ?????* the context from which a view name is to be resolved ?????* @return the view name (or <code>null</code> if no default found) ?????* @throws Exception if view name translation fails ?????*/ ????String getViewName(HttpServletRequest request) throws?Exception; }

?

?

?

  • 調(diào)用LocaleResolver接口的resolveLocale方法;

?

?

1 Locale resolveLocale(HttpServletRequest request);
  • 調(diào)用ViewResolver接口的resolveViewName方法,返回view對象

?

?

1 View resolveViewName(String viewName, Locale locale) throws?Exception;
  • 調(diào)用render方法渲染出頁面

超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生

總結(jié)

以上是生活随笔為你收集整理的springMVC 的工作原理和机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。