
21. Web MVC框架
21.1 Spring Web MVC框架簡介
Spring Web模型 - 視圖 - 控制器(MVC)框架是圍繞一個 DispatcherServlet
派發(fā)請求處理程序,具有可配置的處理程序映射,視圖分辨率,區(qū)域設(shè)置,時區(qū)和主題解析以及支持上載文件的。默認(rèn)處理程序是基于@Controller
和@RequestMapping
注釋,提供了廣泛的靈活的處理方法。隨著Spring 3.0的推出,該@Controller
機(jī)制還允許您通過@PathVariable
注釋和其他功能創(chuàng)建RESTful Web站點(diǎn)和應(yīng)用程序。
“Open for extension ...”Spring Web MVC和Spring中的一個關(guān)鍵設(shè)計原則是“ Open for extension,closed for modification ”原則。
Spring Web MVC的核心類中的一些方法被標(biāo)記final
。作為一名開發(fā)人員,您無法重寫這些方法來提供您自己的行為。這不是任意的,而是專門針對這一原則。
有關(guān)這個原理的解釋,請參閱Seth Ladd等人的Expert Spring Web MVC和Web Flow ; 具體請參閱第一版117頁的“設(shè)計看看”一節(jié)?;蛘?,看
當(dāng)您使用Spring MVC時,不能將建議添加到最終方法中。例如,您不能向該AbstractController.setSynchronizeOnSession()
方法添加建議。請參閱 第10.6.1節(jié)“了解AOP代理”以獲取有關(guān)AOP代理的更多信息,以及為什么不能將建議添加到最終方法。
在Spring Web MVC中,可以使用任何對象作為命令或形式支持對象; 您不需要實(shí)現(xiàn)特定于框架的接口或基類。Spring的數(shù)據(jù)綁定非常靈活:例如,它將類型不匹配視為可由應(yīng)用程序評估的驗(yàn)證錯誤,而不是系統(tǒng)錯誤。因此,您不需要將您的業(yè)務(wù)對象的屬性復(fù)制為表單對象中簡單的非類型化字符串,只是為了處理無效的提交,或者正確地轉(zhuǎn)換字符串。相反,通常最好直接綁定到您的業(yè)務(wù)對象。
Spring的視圖分辨率非常靈活。A Controller
通常負(fù)責(zé)Map
使用數(shù)據(jù)準(zhǔn)備模型并選擇視圖名稱,但也可以直接寫入響應(yīng)流并完成請求。通過文件擴(kuò)展名或者Accept頭內(nèi)容類型協(xié)商,通過bean名稱,屬性文件甚至自定義ViewResolver
實(shí)現(xiàn),視圖名稱解析是高度可配置的。模型(MVC中的M)是一個Map
接口,它允許視圖技術(shù)的完整抽象。您可以直接與基于模板的渲染技術(shù)(如JSP,Velocity和Freemarker)進(jìn)行集成,也可以直接生成XML,JSON,Atom和許多其他類型的內(nèi)容。該模型Map
簡單地轉(zhuǎn)換成適當(dāng)?shù)母袷剑鏙SP請求屬性,Velocity模板模型。
21.1.1 Spring Web MVC的特性
Spring Web Flow
Spring Web Flow(SWF)旨在成為Web應(yīng)用程序頁面流程管理的最佳解決方案。
SWF與Spring MVC和JSF等現(xiàn)有框架集成在Servlet和Portlet環(huán)境中。如果您有一個業(yè)務(wù)流程(或多個流程)可以從對話模型中獲益,而不是純粹的請求模型,那么SWF可能就是解決方案。
SWF允許您將邏輯頁面流作為獨(dú)立模塊進(jìn)行捕獲,這些模塊可在不同情況下重復(fù)使用,因此非常適合構(gòu)建通過受控導(dǎo)航來引導(dǎo)業(yè)務(wù)流程來指導(dǎo)用戶的Web應(yīng)用程序模塊。
有關(guān)SWF的更多信息,請參閱 Spring Web Flow網(wǎng)站。
Spring的Web模塊包含許多獨(dú)特的Web支持功能:
明確區(qū)分角色。每個角色 - 控制器,驗(yàn)證器,命令對象,表單對象,模型對象DispatcherServlet
,處理程序映射,視圖解析器等 - 都可以由專門的對象來實(shí)現(xiàn)。
強(qiáng)大而直接的框架和應(yīng)用程序類的配置,如JavaBeans。此配置功能包括跨上下文的簡單引用,例如從Web控制器到業(yè)務(wù)對象和驗(yàn)證程序。
適應(yīng)性,非侵入性和靈活性。定義您需要的任何控制器方法簽名,可能使用某個參數(shù)注釋(例如@RequestParam,@RequestHeader,@PathVariable等)來執(zhí)行給定的方案。
可重復(fù)使用的業(yè)務(wù)代碼,不需要重復(fù)。使用現(xiàn)有的業(yè)務(wù)對象作為命令或表單對象,而不是鏡像它們來擴(kuò)展特定的框架基類。
可定制的綁定和驗(yàn)證。將不匹配項視為應(yīng)用程序級驗(yàn)證錯誤,從而保留違規(guī)值,本地化日期和數(shù)字綁定等,而不是手動分析和轉(zhuǎn)換為業(yè)務(wù)對象的僅字符串表單對象。
可定制的處理程序映射和視圖解析。處理程序映射和視圖分辨率策略的范圍從簡單的基于URL的配置到復(fù)雜的專用解析策略。Spring比web MVC框架更靈活,它要求一個特定的技術(shù)。
靈活的模型轉(zhuǎn)移。具有名稱/值的模型傳輸Map
支持與任何視圖技術(shù)輕松集成。
可定制的語言環(huán)境,時區(qū)和主題解析,支持帶有或不帶有Spring標(biāo)簽庫的JSP,支持JSTL,支持Velocity而不需要額外的橋接,等等。
一個簡單而強(qiáng)大的JSP標(biāo)簽庫,被稱為Spring標(biāo)簽庫,提供對數(shù)據(jù)綁定和主題等功能的支持。自定義標(biāo)簽允許在標(biāo)記代碼方面有最大的靈活性。有關(guān)標(biāo)記庫描述符的信息,請參閱附錄,標(biāo)題為 Chapter 42,Spring JSP Tag Library
在Spring 2.0中引入了一個JSP表單標(biāo)簽庫,它使JSP頁面中的表單變得更容易。有關(guān)標(biāo)記庫描述符的信息,請參閱附錄標(biāo)題為“ Spring-form JSP標(biāo)記庫 ”的第43章
Bean的生命周期范圍為當(dāng)前的HTTP請求或HTTP Session
。 這不是Spring MVC本身的特定功能,而是WebApplicationContext
Spring MVC使用的 容器。這些bean作用域在第6.5.4節(jié)“請求,會話和全局會話作用域”
21.1.2其他MVC實(shí)現(xiàn)的可插入性
對于某些項目來說,非Spring MVC實(shí)現(xiàn)更可取。許多團(tuán)隊希望利用他們現(xiàn)有的技能和工具投資,例如JSF。
如果您不想使用Spring的Web MVC,但是打算利用Spring提供的其他解決方案,則可以輕松地將您所選擇的Web MVC框架與Spring集成。簡單地通過它啟動一個Spring根應(yīng)用程序上下文 ContextLoaderListener
,并通過其ServletContext
屬性(或Spring的相應(yīng)的輔助方法)從任何操作對象中訪問它。不涉及“插件”,所以不需要專門的集成。從Web層的角度來看,只需使用Spring作為庫,并以根應(yīng)用程序上下文實(shí)例作為入口點(diǎn)。
即使沒有Spring的Web MVC,你注冊的bean和Spring的服務(wù)也可以在你的指尖。在這種情況下,Spring不會與其他Web框架競爭。它只是簡單地解決了純Web的MVC框架所沒有的許多領(lǐng)域,從bean配置到數(shù)據(jù)訪問和事務(wù)處理。因此,即使您只是想使用JDBC或Hibernate的事務(wù)抽象,也可以使用Spring中間層和/或數(shù)據(jù)訪問層來豐富您的應(yīng)用程序。
21.2 DispatcherServlet
Spring的web MVC框架和許多其他的web MVC框架一樣,是以請求為驅(qū)動的,圍繞一個中央Servlet進(jìn)行設(shè)計,這個中央Servlet將請求分發(fā)給控制器,并提供其他功能來促進(jìn)Web應(yīng)用程序的開發(fā)。DispatcherServlet
然而,春天 不止于此。它與Spring IoC容器完全集成,因此可以使用Spring提供的其他所有功能。
Spring Web MVC的請求處理工作流程DispatcherServlet
如下圖所示。精通模式的讀者會認(rèn)識到,這 DispatcherServlet
是“Front Controller”設(shè)計模式(這是Spring Web MVC與許多其他領(lǐng)先的Web框架共享的模式)的表達(dá)。
圖21.1。Spring Web MVC中的請求處理工作流(高級)
這DispatcherServlet
是一個實(shí)際的Servlet
(它從HttpServlet
基類繼承),并且這是在web.xml
你的Web應(yīng)用程序中聲明的。您需要映射要DispatcherServlet
處理的請求,方法是使用同一個web.xml
文件中的URL映射。這是標(biāo)準(zhǔn)的Java EE Servlet配置; 下面的例子顯示了這樣一個DispatcherServlet
聲明和映射:
exampleorg.springframework.web.servlet.DispatcherServlet1example/example/*
在前面的示例中,所有以開頭的請求/example
將由DispatcherServlet
名為的實(shí)例處理 example
。在Servlet 3.0+環(huán)境中,您也可以選擇以編程方式配置Servlet容器。以下是基于代碼的上面web.xml
例子的等價物:
public class MyWebApplicationInitializer implements WebApplicationInitializer { @Overridepublic void onStartup(ServletContext container) {ServletRegistration.Dynamic registration = container.addServlet('dispatcher', new DispatcherServlet());registration.setLoadOnStartup(1);registration.addMapping('/example/*');}}