SpringMVC入門——學(xué)SpringMVC

2.1、Spring Web MVC是什么

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)模型,框架的目的就是幫助我們簡(jiǎn)化開發(fā),Spring Web MVC也是要簡(jiǎn)化我們?nèi)粘eb開發(fā)的。

創(chuàng)新互聯(lián)公司是一家朝氣蓬勃的網(wǎng)站建設(shè)公司。公司專注于為企業(yè)提供信息化建設(shè)解決方案。從事網(wǎng)站開發(fā),網(wǎng)站制作,網(wǎng)站設(shè)計(jì),網(wǎng)站模板,微信公眾號(hào)開發(fā),軟件開發(fā),小程序設(shè)計(jì),十余年建站對(duì)成都紙箱等多個(gè)方面,擁有豐富的網(wǎng)站建設(shè)經(jīng)驗(yàn)。

 

另外還有一種基于組件的、事件驅(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)先原則)的契約式編程支持。

2.2、Spring Web MVC能幫我們做什么

√讓我們能非常簡(jiǎn)單的設(shè)計(jì)出干凈的Web層和薄薄的Web層;

√進(jìn)行更簡(jiǎn)潔的Web層的開發(fā);

√天生與Spring框架集成(如IoC容器、AOP等);

√提供強(qiáng)大的約定大于配置的契約式編程支持;

√能簡(jiǎn)單的進(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)簽庫,簡(jiǎn)化JSP開發(fā);

√支持靈活的本地化、主題等解析;

√更加簡(jiǎn)單的異常處理;

√對(duì)靜態(tài)資源的支持;

√支持Restful風(fēng)格。

2.3、Spring Web MVC架構(gòu)

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.3.1、Spring Web MVC處理請(qǐng)求的流程

如圖2-1

 Spring MVC入門 —— 學(xué)SpringMVC

圖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ù),在后邊依次回答。

 

2.3.2、Spring Web MVC架構(gòu)

1、Spring Web MVC核心架構(gòu)圖,如圖2-2

 Spring MVC入門 —— 學(xué)SpringMVC

圖2-2

 

 

架構(gòu)圖對(duì)應(yīng)的DispatcherServlet核心代碼如下:

 

java代碼:

Java代碼  Spring MVC入門 —— 學(xué)SpringMVC

  1. //前端控制器分派方法  

  2. protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {  

  3.         HttpServletRequest processedRequest = request;  

  4.         HandlerExecutionChain mappedHandler = null;  

  5.         int interceptorIndex = -1;  

  6.   

  7.         try {  

  8.             ModelAndView mv;  

  9.             boolean errorView = false;  

  10.   

  11.             try {  

  12.                    //檢查是否是請(qǐng)求是否是multipart(如文件上傳),如果是將通過MultipartResolver解析  

  13.                 processedRequest = checkMultipart(request);  

  14.                    //步驟2、請(qǐng)求到處理器(頁面控制器)的映射,通過HandlerMapping進(jìn)行映射  

  15.                 mappedHandler = getHandler(processedRequest, false);  

  16.                 if (mappedHandler == null || mappedHandler.getHandler() == null) {  

  17.                     noHandlerFound(processedRequest, response);  

  18.                     return;  

  19.                 }  

  20.                    //步驟3、處理器適配,即將我們的處理器包裝成相應(yīng)的適配器(從而支持多種類型的處理器)  

  21.                 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());  

  22.   

  23.                   // 304 Not Modified緩存支持  

  24.                 //此處省略具體代碼  

  25.   

  26.                 // 執(zhí)行處理器相關(guān)的攔截器的預(yù)處理(HandlerInterceptor.preHandle)  

  27.                 //此處省略具體代碼  

  28.   

  29.                 // 步驟4、由適配器執(zhí)行處理器(調(diào)用處理器相應(yīng)功能處理方法)  

  30.                 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());  

  31.   

  32.                 // Do we need view name translation?  

  33.                 if (mv != null && !mv.hasView()) {  

  34.                     mv.setViewName(getDefaultViewName(request));  

  35.                 }  

  36.   

  37.                 // 執(zhí)行處理器相關(guān)的攔截器的后處理(HandlerInterceptor.postHandle)  

  38.                 //此處省略具體代碼  

  39.             }  

  40.             catch (ModelAndViewDefiningException ex) {  

  41.                 logger.debug("ModelAndViewDefiningException encountered", ex);  

  42.                 mv = ex.getModelAndView();  

  43.             }  

  44.             catch (Exception ex) {  

  45.                 Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);  

  46.                 mv = processHandlerException(processedRequest, response, handler, ex);  

  47.                 errorView = (mv != null);  

  48.             }  

  49.   

  50.             //步驟5 步驟6、解析視圖并進(jìn)行視圖的渲染  

  51. //步驟5 由ViewResolver解析View(viewResolver.resolveViewName(viewName, locale))  

  52. //步驟6 視圖在渲染時(shí)會(huì)把Model傳入(view.render(mv.getModelInternal(), request, response);)  

  53.             if (mv != null && !mv.wasCleared()) {  

  54.                 render(mv, processedRequest, response);  

  55.                 if (errorView) {  

  56.                     WebUtils.clearErrorRequestAttributes(request);  

  57.                 }  

  58.             }  

  59.             else {  

  60.                 if (logger.isDebugEnabled()) {  

  61.                     logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +  

  62.                             "': assuming HandlerAdapter completed request handling");  

  63.                 }  

  64.             }  

  65.   

  66.             // 執(zhí)行處理器相關(guān)的攔截器的完成后處理(HandlerInterceptor.afterCompletion)  

  67.             //此處省略具體代碼  

  68.   

  69.   

  70.         catch (Exception ex) {  

  71.             // Trigger after-completion for thrown exception.  

  72.             triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);  

  73.             throw ex;  

  74.         }  

  75.         catch (Error err) {  

  76.             ServletException ex = new NestedServletException("Handler processing failed", err);  

  77.             // Trigger after-completion for thrown exception.  

  78.             triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);  

  79.             throw ex;  

  80.         }  

  81.   

  82.         finally {  

  83.             // Clean up any resources used by a multipart request.  

  84.             if (processedRequest != request) {  

  85.                 cleanupMultipart(processedRequest);  

  86.             }  

  87.         }  

  88.     }  

 

核心架構(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)證。

 

2.4、Spring Web MVC優(yōu)勢(shì)

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等能夠非常簡(jiǎn)單的定制;

7、功能強(qiáng)大的數(shù)據(jù)驗(yàn)證、格式化、綁定機(jī)制;

8、利用Spring提供的Mock對(duì)象能夠非常簡(jiǎn)單的進(jìn)行Web層單元測(cè)試;

9、本地化、主題的解析的支持,使我們更容易進(jìn)行國際化和主題的切換。

10、強(qiáng)大的JSP標(biāo)簽庫,使JSP編寫更容易。

………………還有比如RESTful風(fēng)格的支持、簡(jiǎn)單的文件上傳、約定大于配置的契約式編程支持、基于注解的零配置支持等等。

 

到此我們已經(jīng)簡(jiǎn)單的了解了Spring Web MVC,接下來讓我們來個(gè)實(shí)例來具體使用下這個(gè)框架。

2.5、Hello World入門

2.5.1、準(zhǔn)備開發(fā)環(huán)境和運(yùn)行環(huán)境:

☆開發(fā)工具:eclipse

☆運(yùn)行環(huán)境:tomcat6.0.20

☆工程:動(dòng)態(tài)web工程(springmvc-chapter2)

☆spring框架下載:

spring-framework-3.1.1.RELEASE-with-docs.zip

☆依賴jar包:

1、  Spring框架jar包:

為了簡(jiǎn)單,將spring-framework-3.1.1.RELEASE-with-docs.zip/dist/下的所有jar包拷貝到項(xiàng)目的WEB-INF/lib目錄下;

2、  Spring框架依賴的jar包:

需要添加Apache commons logging日志,此處使用的是commons.logging-1.1.1.jar;

需要添加jstl標(biāo)簽庫支持,此處使用的是jstl-1.1.2.jar和standard-1.1.2.jar;

2.5.2、前端控制器的配置

在我們的web.xml中添加如下配置:

 

java代碼:

Java代碼  Spring MVC入門 —— 學(xué)SpringMVC

  1. <servlet>  

  2.     <servlet-name>chapter2</servlet-name>  

  3.     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  

  4.     <load-on-startup>1</load-on-startup>  

  5. </servlet>  

  6. <servlet-mapping>  

  7.     <servlet-name>chapter2</servlet-name>  

  8.     <url-pattern>/</url-pattern>  

  9. </servlet-mapping>  

load-on-startup:表示啟動(dòng)容器時(shí)初始化該Servlet;

url-pattern:表示哪些請(qǐng)求交給Spring Web MVC處理, “/” 是用來定義默認(rèn)servlet映射的。也可以如“*.html”表示攔截所有以html為擴(kuò)展名的請(qǐng)求。

 

自此請(qǐng)求已交給Spring Web MVC框架處理,因此我們需要配置Spring的配置文件,默認(rèn)DispatcherServlet會(huì)加載WEB-INF/[DispatcherServlet的Servlet名字]-servlet.xml配置文件。本示例為WEB-INF/ chapter2-servlet.xml。

 

2.5.3、在Spring配置文件中配置HandlerMapping、HandlerAdapter

具體配置在WEB-INF/ chapter2-servlet.xml文件中:

 

java代碼:

Java代碼  Spring MVC入門 —— 學(xué)SpringMVC

  1. <!-- HandlerMapping -->  

  2. <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>  

  3.    

  4. <!-- HandlerAdapter -->  

  5. <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>  

 

BeanNameUrlHandlerMapping:表示將請(qǐng)求的URL和Bean名字映射,如URL為 “上下文/hello”,則Spring配置文件必須有一個(gè)名字為“/hello”的Bean,上下文默認(rèn)忽略。

SimpleControllerHandlerAdapter:表示所有實(shí)現(xiàn)了org.springframework.web.servlet.mvc.Controller接口的Bean可以作為Spring Web MVC中的處理器。如果需要其他類型的處理器可以通過實(shí)現(xiàn)HadlerAdapter來解決。

2.5.4、在Spring配置文件中配置ViewResolver

具體配置在WEB-INF/ chapter2-servlet.xml文件中:

 

java代碼:

Java代碼  Spring MVC入門 —— 學(xué)SpringMVC

  1. <!-- ViewResolver -->  

  2. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  

  3.     <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>  

  4.     <property name="prefix" value="/WEB-INF/jsp/"/>  

  5.     <property name="suffix" value=".jsp"/>  

  6. </bean>  

 

InternalResourceViewResolver:用于支持Servlet、JSP視圖解析;

    viewClass:JstlView表示JSP模板頁面需要使用JSTL標(biāo)簽庫,classpath中必須包含jstl的相關(guān)jar包;

    prefix和suffix:查找視圖頁面的前綴和后綴(前綴[邏輯視圖名]后綴),比如傳進(jìn)來的邏輯視圖名為hello,則該該jsp視圖頁面應(yīng)該存放在“WEB-INF/jsp/hello.jsp”;

 

2.5.5、開發(fā)處理器/頁面控制器

 

java代碼:

Java代碼  Spring MVC入門 —— 學(xué)SpringMVC

  1. package cn.javass.chapter2.web.controller;  

  2. import javax.servlet.http.HttpServletRequest;  

  3. import javax.servlet.http.HttpServletResponse;  

  4. import org.springframework.web.servlet.ModelAndView;  

  5. import org.springframework.web.servlet.mvc.Controller;   分享名稱:SpringMVC入門——學(xué)SpringMVC
    文章出自:http://muchs.cn/article44/geophe.html

    成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、外貿(mào)建站品牌網(wǎng)站設(shè)計(jì)、電子商務(wù)、品牌網(wǎng)站建設(shè)、網(wǎng)站排名

    廣告

    聲明:本網(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)

成都定制網(wǎng)站建設(shè)