這是一個SpringMVC的學習筆記
基本上是一個精簡版的SpringMVC參考,很簡單,因為大部分的web框架的概念都是通用的。
而本文更關心的是SpringMVC中的概念性問題,至于細節,不在本學習筆記之內。
該文檔基于Spring2.5.2
概述
Spring的web框架圍繞DispatcherServlet設計。 DispatcherServlet的作用是將請求分發到不同的處理器。 Spring的web框架包括可配置的處理器(handler)映射、視圖(view)解析、本地化(local)解析、 主題(theme)解析以及對 文件上傳 的支持。Spring的Web框架中缺省的處理器是Controller 接口,這是一個非常簡單的接口,僅包含ModelAndView handleRequest(request, response) 方法。可以通過實現這個接口來創建自己的控制器(也可以稱之為處理器),但是更推薦繼承Spring提供的一系列控制器, 比如AbstractController、AbstractCommandController 和SimpleFormController。
Spring Web MVC框架的特點
清晰的角色劃分:控制器(controller)、驗證器(validator)、 命令對象(command object)、表單對象(form object)、模型對象(model object)、 Servlet分發器(DispatcherServlet)、 處理器映射(handler mapping)、視圖解析器(view resolver)等等。 每一個角色都可以由一個專門的對象來實現。
強大而直接的配置方式:將框架類和應用程序類都能作為JavaBean配置,支持跨多個context的引用,例如,在web控制器中對業務對象和驗證器(validator)的引用。
可適配、非侵入:可以根據不同的應用場景,選擇合適的控制器子類 (simple型、command型、form型、wizard型、multi-action型或者自定義),而不是從單一控制器 (比如Action/ActionForm)繼承。
可重用的業務代碼:可以使用現有的業務對象作為命令或表單對象,而不需要去擴展某個特定框架的基類。
可定制的綁定(binding) 和驗證(validation):比如將類型不匹配作為應用級的驗證錯誤, 這可以保存錯誤的值。再比如本地化的日期和數字綁定等等。
可定制的handler mapping和view resolution:Spring提供從最簡單的URL映射, 到復雜的、專用的定制策略。
靈活的model轉換:在Springweb框架中,使用基于Map的 鍵/值對來達到輕易地與各種視圖技術的集成。
可定制的本地化和主題(theme)解析:支持在JSP中可選擇地使用Spring標簽庫、支持JSTL、支持Velocity(不需要額外的中間層)等等。
簡單而強大的JSP標簽庫(Spring Tag Library):支持包括諸如數據綁定和主題(theme) 之類的許多功能。它提供在標記方面的最大靈活性。
JSP表單標簽庫:在Spring2.0中引入的表單標簽庫,使得在JSP中編寫 表單更加容易。
Spring Bean的生命周期可以被限制在當前的HTTP Request或者HTTP Session。 準確的說,這并非Spring MVC框架本身特性,而應歸屬于Sping MVC使用的WebApplicationContext容器。
這個圖是很通用的一個mvc的圖,基本上主流的web框架都是這么做。
控制器
控制器的概念是MVC設計模式的一部分(確切地說,是MVC中的C)。應用程序的行為通常被定義為服務接口, 而控制器使得用戶可以訪問應用所提供的服務。控制器解析用戶輸入,并將其轉換成合理的模型數據,從而可以進一步由視圖展示給用戶。 Spring以一種抽象的方式實現了控制器概念,這樣可以支持不同類型的控制器。
控制器還是推薦一個request一個controller的方式,向導型除外。
為提供一套基礎設施,所有的Spring控制器都繼承了 AbstractController ,AbstractController 提供了諸如緩存支持和mimetype設置這樣的功能。
Spring提供了MultiActionController來將多個請求處理方法合并在一個控制器里,這樣可以把相關功能組合在一起。
Spring的command controllers是Spring MVC的重要部分。 命令控制器提供了一種和數據對象交互的方式,并動態地將來自HttpServletRequest的參數綁定到指定的數據對象上。
處理器映射
HandlerMapping的基本功能是將請求傳遞到HandlerExecutionChain上。 首先,這個HandlerExecutionChain必須包含一個能處理該請求的處理器。 其次,這個鏈也可以包含一系列可以攔截請求的攔截器。 當收到請求時,DispatcherServlet將請求交給處理器映射,讓它檢查請求并找到一個適當的HandlerExecutionChain。 然后,DispatcherServlet執行定義在鏈中的處理器和攔截器(interceptor)。
在處理器映射中通過配置攔截器(包括處理器執行前、執行后、或者執行前后運行攔截器)將使其功能更強大。 同時也可以通過自定義HandlerMapping來支持更多的功能。 比如,一個自定義的處理器映射不僅可以根據請求的URL,而且還可以根據和請求相關的特定session狀態來選擇處理器。
攔截器
Spring的處理器映射支持攔截器。當你想要為某些請求提供特殊功能時,例如對用戶進行身份認證,這就非常有用。
打log,測性能,做授權與認證就靠它了。
處理器映射中的攔截器必須實現org.springframework.web.servlet包中的HandlerInterceptor接口。 這個接口定義了三個方法,一個在處理器執行前被調用,一個在處理器執行后被調用,另一個在整個請求處理完后調用。 這三個方法提供你足夠的靈活度做任何處理前后的操作。
視圖與視圖解析
ViewResolver和View是Spring的視圖處理方式中特別重要的兩個接口。 ViewResolver提供了從視圖名稱到實際視圖的映射。 View處理請求的準備工作,并將該請求提交給某種具體的視圖技術。
視圖解析鏈
Spring支持多個視圖解析器一起使用。可以把它們當作一個解析鏈。 這樣有很多好處,比如在特定情況下重新定義某些視圖。 定義視圖解析鏈很容易,只要在應用上下文中定義多個解析器就可以了。 必要時,也可以通過order屬性來聲明每個解析器的序列。
如果某個解析器沒有找到合適的視圖,Spring會在上下文中尋找是否配置了其它的解析器。 如果有,它會繼續進行解析,否則,Srping會拋出一個Exception。
要記住,當一個視圖解析器找不到合適的視圖時,它可能 返回null值。 但是,不是每個解析器都這么做。這是因為,在某些情況下,解析器可能無法偵測出符合要求的視圖是否存在。 比如,InternalResourceViewResolver在內部調用了RequestDispatcher。 請求分發是檢查一個JSP文件是否存在的唯一方法,不幸的是,這個方法只能用一次。 同樣的問題在VelocityViewResolver和其它解析器中也有。 當使用這些解析器時,最好仔細閱讀它們的Javadoc,看看需要的解析器是否無法發現不存在的視圖。 這個問題產生的副作用是,如果InternalResourceViewResolver解析器沒有放在鏈的末端, InternalResourceViewResolver后面的那些解析器根本得不到使用, 因為InternalResourceViewResolver總是返回一個視圖!
重定向(Rediret)到另一個視圖
在控制器中強制重定向的方法之一是讓控制器創建并返回一個Spring的RedirectView的實例。 在這種情況下,DispatcherServlet不會使用通常的視圖解析機制, 既然它已經拿到了一個(重定向)視圖,它就讓這個視圖去完成余下的工作。
盡管使用RedirectView幫我們達到了目的,但是如果控制器生成RedirectView的話, 控制器不可避免地要知道某個請求的結果是讓用戶重定向到另一個頁面。這不是最佳的實現,因為這使得系統不同模塊之間結合得過于緊密。 其實控制器不應該過問返回結果是如何生成的,通常情況下,它應該只關心注入給它的視圖名稱。
解決上述問題的方法是依靠redirect:前綴。 如果返回的視圖名包含redirect:前綴,UrlBasedViewResolver (以及它的子類) 會知道系統要生成一個HTTP redirect。 視圖名其余的部分會被當作重定向URL。
即時是web編程也要考慮松耦合的問題。
本地化解析器
Spring架構的絕大部分都支持國際化,Spring的web MVC框架也不例外。 DispatcherServlet 允許使用客戶端本地化信息自動解析消息。 這個工作由LocaleResolver對象完成。
當收到請求時,DispatcherServlet查找一個本地化解析器,如果找到,就使用它設置本地化信息。 通過RequestContext.getLocale()方法,總可以獲取由本地化解析器解析的客戶端的本地化信息。
使用主題
Sping的web MVC框架允許你通過主題(theme)來控制網頁的風格,這將進一步改善用戶的體驗。 簡單來說,一個主題就是一組靜態的資源(比如樣式表和圖片),它們可以影響應用程序的視覺效果。
這個東西挺好的,不知道有沒有人用起來。
Spring對分段 文件上傳 (multipart file upload)的支持
Spring的表單標簽庫
處理異常
當與請求匹配的控制器處理請求時,可能會發生意料之外的異常。
慣例優先原則
對于很多項目來說,嚴格遵從已有慣例和使用合理的缺省選項大概是這些項目需要的……現在Spring Web MVC明確的支持了這種慣例優先原則的主旨。 這意味著,如果建立了一套命名規范,諸如此類,就可以顯著地減少系統所需配置項目的數量, 來建立處理器映射、視圖解析器、ModelAndView實例,等等。 這為快速原型開發提供了很大方便。同時提供了一定程度的(通常是好事情)代碼庫的一致性,進而可以從中選擇并發展為成型產品。
基于注解的控制器配置
使用@Controller定義一個控制器
使用@RequestMapping映射請求
使用@RequestParam綁定請求參數到方法參數
使用@ModelAttribute提供一個從模型到數據的鏈接
使用@SessionAttributes指定存儲在會話中的屬性
基本上是一個精簡版的SpringMVC參考,很簡單,因為大部分的web框架的概念都是通用的。
而本文更關心的是SpringMVC中的概念性問題,至于細節,不在本學習筆記之內。
該文檔基于Spring2.5.2
概述
Spring的web框架圍繞DispatcherServlet設計。 DispatcherServlet的作用是將請求分發到不同的處理器。 Spring的web框架包括可配置的處理器(handler)映射、視圖(view)解析、本地化(local)解析、 主題(theme)解析以及對 文件上傳 的支持。Spring的Web框架中缺省的處理器是Controller 接口,這是一個非常簡單的接口,僅包含ModelAndView handleRequest(request, response) 方法。可以通過實現這個接口來創建自己的控制器(也可以稱之為處理器),但是更推薦繼承Spring提供的一系列控制器, 比如AbstractController、AbstractCommandController 和SimpleFormController。
Spring Web MVC框架的特點
清晰的角色劃分:控制器(controller)、驗證器(validator)、 命令對象(command object)、表單對象(form object)、模型對象(model object)、 Servlet分發器(DispatcherServlet)、 處理器映射(handler mapping)、視圖解析器(view resolver)等等。 每一個角色都可以由一個專門的對象來實現。
強大而直接的配置方式:將框架類和應用程序類都能作為JavaBean配置,支持跨多個context的引用,例如,在web控制器中對業務對象和驗證器(validator)的引用。
可適配、非侵入:可以根據不同的應用場景,選擇合適的控制器子類 (simple型、command型、form型、wizard型、multi-action型或者自定義),而不是從單一控制器 (比如Action/ActionForm)繼承。
可重用的業務代碼:可以使用現有的業務對象作為命令或表單對象,而不需要去擴展某個特定框架的基類。
可定制的綁定(binding) 和驗證(validation):比如將類型不匹配作為應用級的驗證錯誤, 這可以保存錯誤的值。再比如本地化的日期和數字綁定等等。
可定制的handler mapping和view resolution:Spring提供從最簡單的URL映射, 到復雜的、專用的定制策略。
靈活的model轉換:在Springweb框架中,使用基于Map的 鍵/值對來達到輕易地與各種視圖技術的集成。
可定制的本地化和主題(theme)解析:支持在JSP中可選擇地使用Spring標簽庫、支持JSTL、支持Velocity(不需要額外的中間層)等等。
簡單而強大的JSP標簽庫(Spring Tag Library):支持包括諸如數據綁定和主題(theme) 之類的許多功能。它提供在標記方面的最大靈活性。
JSP表單標簽庫:在Spring2.0中引入的表單標簽庫,使得在JSP中編寫 表單更加容易。
Spring Bean的生命周期可以被限制在當前的HTTP Request或者HTTP Session。 準確的說,這并非Spring MVC框架本身特性,而應歸屬于Sping MVC使用的WebApplicationContext容器。
這個圖是很通用的一個mvc的圖,基本上主流的web框架都是這么做。


控制器
控制器的概念是MVC設計模式的一部分(確切地說,是MVC中的C)。應用程序的行為通常被定義為服務接口, 而控制器使得用戶可以訪問應用所提供的服務。控制器解析用戶輸入,并將其轉換成合理的模型數據,從而可以進一步由視圖展示給用戶。 Spring以一種抽象的方式實現了控制器概念,這樣可以支持不同類型的控制器。
控制器還是推薦一個request一個controller的方式,向導型除外。
為提供一套基礎設施,所有的Spring控制器都繼承了 AbstractController ,AbstractController 提供了諸如緩存支持和mimetype設置這樣的功能。
Spring提供了MultiActionController來將多個請求處理方法合并在一個控制器里,這樣可以把相關功能組合在一起。
Spring的command controllers是Spring MVC的重要部分。 命令控制器提供了一種和數據對象交互的方式,并動態地將來自HttpServletRequest的參數綁定到指定的數據對象上。
處理器映射
HandlerMapping的基本功能是將請求傳遞到HandlerExecutionChain上。 首先,這個HandlerExecutionChain必須包含一個能處理該請求的處理器。 其次,這個鏈也可以包含一系列可以攔截請求的攔截器。 當收到請求時,DispatcherServlet將請求交給處理器映射,讓它檢查請求并找到一個適當的HandlerExecutionChain。 然后,DispatcherServlet執行定義在鏈中的處理器和攔截器(interceptor)。
在處理器映射中通過配置攔截器(包括處理器執行前、執行后、或者執行前后運行攔截器)將使其功能更強大。 同時也可以通過自定義HandlerMapping來支持更多的功能。 比如,一個自定義的處理器映射不僅可以根據請求的URL,而且還可以根據和請求相關的特定session狀態來選擇處理器。
攔截器
Spring的處理器映射支持攔截器。當你想要為某些請求提供特殊功能時,例如對用戶進行身份認證,這就非常有用。
打log,測性能,做授權與認證就靠它了。
處理器映射中的攔截器必須實現org.springframework.web.servlet包中的HandlerInterceptor接口。 這個接口定義了三個方法,一個在處理器執行前被調用,一個在處理器執行后被調用,另一個在整個請求處理完后調用。 這三個方法提供你足夠的靈活度做任何處理前后的操作。
視圖與視圖解析
ViewResolver和View是Spring的視圖處理方式中特別重要的兩個接口。 ViewResolver提供了從視圖名稱到實際視圖的映射。 View處理請求的準備工作,并將該請求提交給某種具體的視圖技術。
視圖解析鏈
Spring支持多個視圖解析器一起使用。可以把它們當作一個解析鏈。 這樣有很多好處,比如在特定情況下重新定義某些視圖。 定義視圖解析鏈很容易,只要在應用上下文中定義多個解析器就可以了。 必要時,也可以通過order屬性來聲明每個解析器的序列。
如果某個解析器沒有找到合適的視圖,Spring會在上下文中尋找是否配置了其它的解析器。 如果有,它會繼續進行解析,否則,Srping會拋出一個Exception。
要記住,當一個視圖解析器找不到合適的視圖時,它可能 返回null值。 但是,不是每個解析器都這么做。這是因為,在某些情況下,解析器可能無法偵測出符合要求的視圖是否存在。 比如,InternalResourceViewResolver在內部調用了RequestDispatcher。 請求分發是檢查一個JSP文件是否存在的唯一方法,不幸的是,這個方法只能用一次。 同樣的問題在VelocityViewResolver和其它解析器中也有。 當使用這些解析器時,最好仔細閱讀它們的Javadoc,看看需要的解析器是否無法發現不存在的視圖。 這個問題產生的副作用是,如果InternalResourceViewResolver解析器沒有放在鏈的末端, InternalResourceViewResolver后面的那些解析器根本得不到使用, 因為InternalResourceViewResolver總是返回一個視圖!
重定向(Rediret)到另一個視圖
在控制器中強制重定向的方法之一是讓控制器創建并返回一個Spring的RedirectView的實例。 在這種情況下,DispatcherServlet不會使用通常的視圖解析機制, 既然它已經拿到了一個(重定向)視圖,它就讓這個視圖去完成余下的工作。
盡管使用RedirectView幫我們達到了目的,但是如果控制器生成RedirectView的話, 控制器不可避免地要知道某個請求的結果是讓用戶重定向到另一個頁面。這不是最佳的實現,因為這使得系統不同模塊之間結合得過于緊密。 其實控制器不應該過問返回結果是如何生成的,通常情況下,它應該只關心注入給它的視圖名稱。
解決上述問題的方法是依靠redirect:前綴。 如果返回的視圖名包含redirect:前綴,UrlBasedViewResolver (以及它的子類) 會知道系統要生成一個HTTP redirect。 視圖名其余的部分會被當作重定向URL。
即時是web編程也要考慮松耦合的問題。
本地化解析器
Spring架構的絕大部分都支持國際化,Spring的web MVC框架也不例外。 DispatcherServlet 允許使用客戶端本地化信息自動解析消息。 這個工作由LocaleResolver對象完成。
當收到請求時,DispatcherServlet查找一個本地化解析器,如果找到,就使用它設置本地化信息。 通過RequestContext.getLocale()方法,總可以獲取由本地化解析器解析的客戶端的本地化信息。
使用主題
Sping的web MVC框架允許你通過主題(theme)來控制網頁的風格,這將進一步改善用戶的體驗。 簡單來說,一個主題就是一組靜態的資源(比如樣式表和圖片),它們可以影響應用程序的視覺效果。
這個東西挺好的,不知道有沒有人用起來。
Spring對分段 文件上傳 (multipart file upload)的支持
Spring的表單標簽庫
處理異常
當與請求匹配的控制器處理請求時,可能會發生意料之外的異常。
慣例優先原則
對于很多項目來說,嚴格遵從已有慣例和使用合理的缺省選項大概是這些項目需要的……現在Spring Web MVC明確的支持了這種慣例優先原則的主旨。 這意味著,如果建立了一套命名規范,諸如此類,就可以顯著地減少系統所需配置項目的數量, 來建立處理器映射、視圖解析器、ModelAndView實例,等等。 這為快速原型開發提供了很大方便。同時提供了一定程度的(通常是好事情)代碼庫的一致性,進而可以從中選擇并發展為成型產品。
基于注解的控制器配置
使用@Controller定義一個控制器
使用@RequestMapping映射請求
使用@RequestParam綁定請求參數到方法參數
使用@ModelAttribute提供一個從模型到數據的鏈接
使用@SessionAttributes指定存儲在會話中的屬性
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
