spring的view
http://book.51cto.com/art/200908/147512.htm
24.5.1 View實現原理回顧
總地來說,當前絕大多數的視圖渲染技術都是構建在模板的原理上。我們回想一下,這種基于模板的視圖生成方式在我們的生活中到處可見。
廚師為了能夠提供統一樣式的蛋糕,會使用模子來制作,只要提供不同成分的面團,經過相同的模子壓制,就能夠獲得統一樣式卻不同口味的蛋糕。廚師用的模子(可能木質也可能金屬質地)是不是與我們提供的JSP文件相似?那不同成分的面團跟我們提供的不同的模型數據是否類似?
篆刻后的方印,只要蘸上不同顏色的印泥就能印出同一式樣但不同顏色的印章圖案。方印就是模板,不同的印泥就是要表現的數據,是否可以這么理解呢?
實際上,不管是生活中還是視圖渲染過程中,只要使用模板這種模式,它們的工作原理就是一條路子下來的,如圖24-18所示。
| ? |
| (點擊查看大圖)圖24-18 使用模板的工作原理 |
所以,只要能夠理解當前視圖渲染的實現與生活中這些使用模板的場景之間的共同之處,那么,余下的工作將不再神秘。一個View實現類所要做的,就是使用相應的技術API將模板和最終提供的模型數據合并到一起,最終輸出結果頁面給客戶端,所以,不難想象對應不同視圖技術的View實現是一個什么樣子。
如果我們要使用JSP文件作為模板輸出視圖頁面,那么我們的View實現類可能如代碼清單24-29所示。
代碼清單24-29 基于JSP的View實現類原型代碼示例
JSP模板文件與模型數據的合并(merge)操作將由Web容器(比如Tomcat)來完成,所以,這里我們只是通過Servlet API將合并的工作轉發給Web容器即可。
如果我們使用Velocity模板輸出視圖頁面,那么我們的View實現類可能如代碼清單24-30所示。
代碼清單24-30 基于Velocity的View實現類原型代碼示例
如果我們要使用Excel作為輸出對象,那么我們的View實現類可能如代碼清單24-31所示。
代碼清單24-31 基于Excel的View實現類原型代碼示例
怎么樣?雖然只是原型代碼,但已經足夠說明問題了,不是嗎?實際上,Spring MVC提供的針對各種視圖技術的View實現也是按照同一條路子走下來的,只不過比我們的原型代碼要嚴謹罷了。
24.5.2 可用的View實現類(1)
2009-08-27 16:06 王福強 人民郵電出版社 我要評論(0) 字號:T | T綜合評級:
想讀(1)???在讀(3)???已讀(6)??? 品書齋鑒(2)??? 已有10人發表書評
《Spring揭秘》第24章近距離接觸Spring MVC主要角色,HandlerMapping、Controller、ModelAndView、ViewResolver和View可以算是Spring MVC框架中的"五虎將",它們共同組成了Spring MVC框架的強大軀干。本章對它們進行了詳細的介紹,希望你完成本章內容之后,對它們已經了然于心了。本節為大家介紹可用的View實現類。
AD:
24.5.2 可用的View實現類(1)
Spring MVC提供的View實現類都直接或者間接繼承自org.springframework.web.servlet. view.AbstractView。該類定義了大多數View實現類都需要的一些屬性和簡單的模板化的實現流程。
AbstractView為所有View子類定義的屬性是如下幾個。
private String contentType = DEFAULT_CONTENT_TYPE。DEFAULT_CONTENT_TYPE的內容是"text/html;charset=ISO-8859-1"。我們可以通過contentType的setter方法更改這一默認值。
private String requestContextAttribute。requestContextAttribute屬性是要公開給視圖模板使用的org.springframework.web.servlet.support.RequestContext對應的屬性名,比如,如果setRequestContextAttribute("rc")的話,那么,相應的RequestContext實例將以rc作為鍵放入模型中。這樣,我們就可以在視圖模板中通過rc引用到該RequestContext。通常情況下,如果我們使用Spring提供的自定義標簽,那么不需要公開相應的RequestContext。但如果不使用Spring提供的自定義標簽,那么為了能夠訪問處理過程中所返回的錯誤信息等,就需要通過公開給視圖模板的RequestContext來進行了。可以參考RequestContext的Javadoc文檔了解它能夠賦予我們的能力。
private final Map staticAttributes = new HashMap()。如果視圖有某些靜態屬性,比如頁眉、頁腳的固定信息等,只要將它們加入staticAttributes,那么,AbstractView將保證這些靜態屬性將一并放入模型數據中,最終一起公開給視圖模板。既然所有的View實現子類都繼承自AbstractView,那么它們也就都擁有了指定靜態屬性的能力。比如我們在"面向多視圖類型支持的ViewResolver"中定義視圖映射的時候,為某些具體視圖定義指定了靜態屬性,如下所示:
那么,現在我們就可以像普通的模型數據那樣,在視圖模板中訪問這些靜態屬性,如下所示:
不過,除了通過attributesCSV屬性以CSV字符串形式傳入多個靜態屬性,我們還可以通過attributes屬性以Properties的形式傳入靜態屬性,或者通過attributesMap屬性以Map的形式傳入靜態參數。
AbstractView除了定義了以上公共屬性以外,還定義了一個簡單的模板化的方法流程。
(1) 將添加的靜態屬性全部導入到現有的模型數據Map中,以便后繼流程在合并視圖模板的時候可以獲取這些數據。
(2) 如果requestContextAttribute被設置(默認為null),則將其一并導入現有的模型數據Map中;
(3) 根據是否要產生下載內容,設置相應的HTTP Header。
(4) 公開renderMergedOutputModel(..)模板方法給子類實現。
這樣,AbstractView的直接或者間接子類,就可以在現有屬性和流程的基礎上進行開發了。
AbstractView中一個主要的擴展類是org.springframework.web.servlet.view.Abs- tractUrlBasedView,AbstractUrlBasedView為子類提供的公共設施很簡單,只有一個String型的url。那些需要根據模板路徑讀入模板文件的View實現,大都屬于AbstractUrlBasedView門下。
AbstractView和AbstractUrlBasedView是所有View實現類的"總統領",那些不需要指定url的View實現類大都歸于AbstractView門下,余下的則由AbstractUrlBasedView管轄。在這樣的前提下,我們再來看各種實際可用的View實現類。
1. 使用JSP技術的View實現
屬于該類別的View實現主要包括:
org.springframework.web.servlet.view.InternalResourceView
org.springframework.web.servlet.view.JstlView
org.springframework.web.servlet.view.tiles.TilesView
org.springframework.web.servlet.view.tiles.TilesJstlView
其中,org.springframework.web.servlet.view.InternalResourceView是面向JSP技術的主要View實現類,它們之間的關系如圖24-19所示。
| ? |
| (點擊查看大圖)圖24-19 使用JSP的View實現類 |
InteralResourceView和JstlView都是面向單一JSP模板的View實現,二者的區別在于J2EE 1.4之前的Web應用程序不支持JSTL。所以,這些Web應用程序只能使用InternalResourceView,而之后的Web應用程序因為支持JSTL,所以,使用JstlView是沒有問題的。TilesView和TilesJstlView之間的區別與InteralResourceView和JstlView是類似的。不過,TilesView和TilesJstlView使用了Struts的Tiles視圖技術,它們支持的是復合JSP視圖。另外,Spring 2.5之后也引入了對Tiles 2(http://tiles.apache.org/)的支持,對應的TilesView實現位于org.springframework.web.servlet. view.tiles2包下面,與org.springframework.web.servlet.view.tiles包下面的Tiles 1.x版本的TilesView和TilesJstlView相區別。
這些使用JSP技術的View實現,雖然可以在"面向多視圖類型的ViewResolver"的映射關系中單獨配置,不過,因為它們有特定于自己的ViewResolver,即InternalResourceViewResolver,所以,更多時候,只需要在使用之前變換一下如下配置中具體的viewClass類型即可:
不過,Tiles視圖的使用與單純的JSP視圖在使用上存在一點兒差異,我們需要為TilesView和TilesJstlView的渲染提供必需的DefinitionsFactory。這個工作可以通過TilesConfigurer類完成,將TilesConfigurer添加到WebApplicationContext之后,它將為容器內的TilesView和TilesJstlView的渲染提供綁定到ServletContext的DefinitionsFactory。TilesConfigurer的配置如下所示:
24.5.2 可用的View實現類(2)
2009-08-27 16:06 王福強 人民郵電出版社 我要評論(0) 字號:T | T綜合評級:
想讀(1)???在讀(3)???已讀(6)??? 品書齋鑒(2)??? 已有10人發表書評
《Spring揭秘》第24章近距離接觸Spring MVC主要角色,HandlerMapping、Controller、ModelAndView、ViewResolver和View可以算是Spring MVC框架中的"五虎將",它們共同組成了Spring MVC框架的強大軀干。本章對它們進行了詳細的介紹,希望你完成本章內容之后,對它們已經了然于心了。本節為大家介紹可用的View實現類。
AD:
24.5.2 可用的View實現類(2)
2. 使用通用模板技術的View實現
通用模板技術現在比較主流的是Velocity和Freemarker。如果我們的Web應用程序要啟用這兩種技術渲染視圖,那么,Spring MVC提供了FreeMarkerView和VelocityView兩種View實現。
因為二者都是基于同樣的理念構建視圖,所以,FreeMarkerView和VelocityView有著共同的父類AbstractTemplateView,它們之間的繼承層次關系如圖24-20所示。
| ? |
| 圖24-20 使用通用模板技術的View實現 |
AbstractTemplateView定義了幾個boolean屬性,讓我們可以決定是否公開暴露某些數據給最終的合并過程,如下所述。
private boolean exposeRequestAttributes = false。是否需要將request中的所有屬性公開給合并過程,默認為false。
private boolean allowRequestOverride = false。是否允許request中的屬性覆蓋Model- AndView中同名的attribute,默認不允許這么做。
private boolean exposeSessionAttributes = false。是否要將session中的屬性公開給視圖模板與模型數據的合并過程,默認不做。
private boolean allowSessionOverride = false。是否允許session中同名的屬性覆蓋掉返回的ModelAndView中的屬性,默認也是不允許這么做。
private boolean exposeSpringMacroHelpers = true。是否需要為Spring提供的宏(macro)公開一個需要的RequestContext對象,默認需要,將以"springMacroRequestContext"為鍵公開一個RequestContext給合并過程。
除了這些,FreeMarkerView和VelocityView自身也定義了幾個屬性可以進一步限定視圖渲染過程,比如VelocityView允許我們通過dateToolAttribute和numberToolAttribute公開Velocity Tools(http:// velocity.apache.org/tools/devel/)的DateTool和NumberTool給模板使用。
FreeMarkerView和VelocityView的使用都有相應的ViewResolver支持,即FreeMarkerView- Resolver和VelocityViewResolver。不過,我們也可以在"面向多視圖類型的ViewResolver"中使用它們。唯一需要注意的就是,使用這兩種視圖類型的時候,不要忘記通過FreeMarker- Configurer和VelocityConfigurer為它們提供渲染過程中使用的模板引擎支持。
3. 面向二進制文檔格式的View實現
該類的View實現主要指Excel和PDF形式的文檔視圖,通過設定合適的contentType,并且本地有相應的應用程序的話,這些文檔將可以在瀏覽器中直接打開,而不是下載保存。
對于Excel形式的視圖,Spring MVC提供了如下兩個抽象類的視圖實現。
AbstractExcelView。使用Apache POI(http:// poi.apache.org/)來構建Excel文檔的View實現類,支持讀入Excel模板文件,子類需要實現buildExcelDocument(..)模板方法,以給出具體的模型數據到模板文件的合并邏輯。
AbstractJExcelView。該抽象類使用JExcel API(http:// www.andykhan.com/jexcelapi/)作為視圖的渲染API,同樣支持現有Excel模板文件的讀入,具體子類也需要通過實現buildExcel- Document(..)模板方法,來實現具體的模型數據到Excel模板文件的合并過程。
兩種面向Excel的View實現類都支持按照Locale讀入不同的Excel模板文件,讀入順序類似于:
(1) fileLocation_zh_CN.xls;
(2) fileLocation_zh.xls;
(3) fileLocation.xls。
也就是說,我們可以為不同地區的用戶提供不同的視圖文件。
對應PDF形式的View實現類只有AbstractPdfView,它將使用iText來構建最終要輸出的PDF文件。應該是API的限制,該類無法讀入PDF形式的模板文件(當然,沒有API的支持,也不可能做到)。我們只能通過該類創建新的PDF文件,然后將模型數據與要輸入的格式一并納入新創建的PDF文件對象中。該類也是抽象類,子類要實現buildPdfDocument(..)模板方法提供具體的輸出邏輯。
因為面向二進制文檔格式的View實現沒有一個統一的模板形式,所以,Spring MVC無法提供通用的View實現類,只能在抽象父類中提供部分共同邏輯的實現,而具體的模型數據如何融入視圖的顯示邏輯,則需要子類在相應的模板方法中給出。
有關面向二進制文檔格式的View實現的使用,我們可能需要使用"面向多視圖類型的ViewResolver",因為沒有特定于二進制文檔格式View實現的ViewResolver可用。
4. 面向JsperReport的View實現
面向JsperReport的View實現允許我們輸出JasperReport生成的相應格式的報表文件,包括HTML格式、CSV格式、Excel格式以及PDF格式。只要我們在ModelAndView中將要合并到報表的數據返回,面向JsperReport的View實現將把這些數據按照指定格式輸出到客戶端。
面向JsperReport的View實現主要包括如下幾個。
AbstractJasperReportsSingleFormatView。只負責輸出單一類型的報表文件的View抽象類,實現了不同模板類型的讀入以及數據的合并操作,將不同報表格式的輸出通過模板方法下發給具體的子類實現,包括: JasperReportsCsvView
JasperReportsHtmlView
JasperReportsPdfView
JasperReportsXlsView
如果只需要根據模型數據輸出單一文檔格式的報表視圖,選擇以上對應的View子類即可。
JasperReportsMultiFormatView。允許根據ModelAndView中的某個模型數據的值來決定輸出何種格式的報表文檔,默認使用"format"作為鍵。當然,我們可以通過setFormatKey (String)來更改這一默認鍵的名稱。
如果在ModelAndView中添加如下數據,并且使用JasperReportsMultiFormatView作為將要使用的View實現:
那么,JasperReportsMultiFormatView最終將通過JasperReportsPdfView輸出PDF格式的報表文檔。關于format的值與具體View實現類之間的關系,如表24-2所示。
表24-2 format的值與具體View實現類之間的關系
format值 | 具體View類型 |
csv | JasperReportsCsvView |
html | JasperReportsHtmlView |
JasperReportsPdfView | |
xls | JasperReportsXlsView |
24.5.3 自定義View實現
2009-08-27 16:23 王福強 人民郵電出版社 我要評論(0) 字號:T | T綜合評級:
想讀(1)???在讀(3)???已讀(6)??? 品書齋鑒(2)??? 已有10人發表書評
《Spring揭秘》第24章近距離接觸Spring MVC主要角色,HandlerMapping、Controller、ModelAndView、ViewResolver和View可以算是Spring MVC框架中的"五虎將",它們共同組成了Spring MVC框架的強大軀干。本章對它們進行了詳細的介紹,希望你完成本章內容之后,對它們已經了然于心了。本節為大家介紹自定義View實現。
AD:
24.5.3 自定義View實現
雖然Spring MVC框架已經提供了足夠多的View實現類支持,但有些情況下依然無法滿足我們的應用要求。不過,好在框架自身對視圖渲染相關關注點的分離,使得擴展并添加自定義View實現類也不是什么難事。
我們要添加的自定義View實現類所處的場景是這樣的: FX系統中的交易等各類信息需要以報表的形式提供給相應顧客以及后臺管理員,所以,在用戶前臺畫面和后臺管理畫面上定義有相應的鏈接。點擊這些鏈接之后,需要返回相應的PDF或者CSV格式的報表文件進行顯示。需求實際上很簡單,不過Spring MVC提供的JasperReport相關的View實現類,以及面向二進制文檔之類的View實現類(包括AbstractPdfView、AbstractExcelView等),都屬于那種根據Web請求實時生成報表文件并輸出的邏輯范疇。對于某些系統來說,這樣的處理是合適的,但FX系統的報表根據法律要求,需要保存3~5年的時間。這些報表將是法律依據,每個顧客的信息,每筆數據的信息都不能遺漏。所以,在FX系統中,這些報表是通過批處理(Batch)在某一個時段全部輸出的,輸出后的信息保持于數據庫中。當前臺畫面或者后臺畫面請求相應報表文件的時候,只需要根據Web請求信息到數據庫中獲取具體的文件名,并將對應的文件輸出到客戶端即可。自定義的View實現類所要做的,只是將已經通過批處理輸出的PDF或者CSV報表文件傳輸給客戶端顯示。
我們可以繼承AbstractView類。不過,既然同樣需要根據URL去獲取文件,直接繼承Abstract- UrlBasedView或許更合適一些。當然,這完全視具體情況而定。代碼清單24-33是我們完成的自定義View實現類StaticPdfView的代碼演示。
代碼清單24-33 用于靜態PDF文件輸出的自定義View實現類代碼示例
十分簡單,不是嗎?只是根據url信息讀取文件,然后通過response輸出到客戶端即可。而View實現類里面所要做的不就是這些嗎?根據具體場景構建視圖內容,然后通過HttpServlet- Response的Writer或者OutputStream,將構建后的視圖內容輸出到客戶端。就這點兒工作!
因為通常的ViewResolver實現都繼承了AbstractViewResolver的默認開啟緩存功能,所以,通過ViewResolver來查找并使用我們的StaticPdfView并非合適的方式。另外,當前場景中,StaticPdfView所需要的url信息是從數據庫獲取的,顯然無法通過相應ViewResolver進行定義(當然,不排除其他場景下結合ViewResolver使用StaticPdfView的情形)。鑒于以上兩點,在相應的Controller內部直接構造StaticPdfView的實例并返回,或許是比較合適的做法。也就是說,在Controller中是直接返回View實例還是返回邏輯視圖名,需要根據情況權衡。在大多數情況下,推薦使用返回邏輯視圖名的做法,但不排除直接返回View實例的情況。StaticPdfUrlViewController提供了一段代碼示例,演示了StaticPdfView的使用,如代碼清單24-34所示。
代碼清單24-34 Controller內StaticPdfView的使用代碼示例
方法getPdfFileLocation(..)將抽取Web請求參數,然后根據這些參數查詢數據庫,并返回對應的PDF文件路徑。具體實現可能隨前后臺之間的參數約定而有少許差異。
注意 通常,自定義View實現類需要結合相應的ViewResolver才能使用,直接在Controller中實例化View并非大部分情況下的做法。對某類View來說,完全可以為其單獨聲明一個ViewResolver,指定合適的優先級別(通過order屬性)。即使現用的ViewResolver無法滿足需要,為某類View實現類提供自定義的ViewResolver實現類也并非難事。各位不妨考慮下,類似StaticPdfView這樣的View實現,除了在Controller中直接實例化,是否可以為其提供一個自定義的ViewResolver呢?
現在你是否準備自定義自己的View實現類了呢?
?
總結
以上是生活随笔為你收集整理的spring的view的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mysql对事务的支持
- 下一篇: spring的ModelAndView