關于SpringMVC映射模型視圖的幾點小事

一.SpringMVC概述

  • SpringMVC為展現層提供的基于MVC設計理念的優秀的Web框架,是目前最主流的MVC框架之一。
  • SpringMVC通過一套MVC注解,讓POJO成為處理請求的控制器,而無需實現任何接口。
  • 支持RESTFUL風格的URL。
  • 采用了松散耦合可插拔組件結構,更具靈活性和擴展性。

二.使用@RequestMapping映射請求

1.使用@RequestMapping映射請求

  • SpringMVC使用@RequestMapping注解為控制器指定可以出來那些URL請求。
  • 在控制器的類定義及方法定義處都可以進行標注。
    • 類定義處:提供初步的請求映射信息。相對于WEB應用的根目錄。
    • 方法處:提供進一步的細分映射信息。相對于類定義處的URL。若類定義處未標注@RequestMapping,則方法標記處的URL相對于WEB應用的根目錄。
  • DispatcherServlet截獲請求后,就通過控制器上@RequestMapping提供的映射信息確定請求所對應的處理方法。

2.映射請求參數、請求方法或請求頭

  • @RequestMapping除了可以使用請求URL映射請求外,還可以使用請求方法、請求參數及請求頭映射請求。
  • @RequestMapping的value、method、params及headers分別表示請求URL、請求方法、請求參數和請求頭的映射條件,他們之間是與的關系,聯合使用可以使請求映射更加精準化。
  • params和headers支持簡單的表達式。
    • param1:表示請求必須包含名為param1的請求參數。
    • !param1:表示請求不能包含名為param1的請求參數。
    • param1 != value1:表示請求包含名為param1的請求參數,但其值不能為value1.
    • {"param1=value","param2"}:請求必須包含名為param1和param2 兩個請求參數,且parma1參數的值必須為value1。

3.使用@RequestMapping映射請求的匹配符

  • Ant風格資源地址支持3種匹配符。
    • ? : 匹配文件名中的一個字符。
    • * :匹配文件名中的任意字符。
    • ** :匹配多層路徑。
  • @RequestMapping還支持Ant風格的URL。
    • /user/*/createUser:匹配/user/aaa/createUser、/user/bbb/createUser等url。
    • /user/**/createUser:匹配/user/createUser、/user/aaa/createUser、/user/aaa/bbb/createUser等URL。
    • /user/createUser??: 匹配/user/createUseraa、/user/createUserbb等URL。

4.使用@PathVariable映射URL綁定的占位符

  • 帶占位符的URL是Spring 3.0新增的功能,該功能在SpringMVC向Rest目標過程中具有重要意義。
  • 通過@PathVeriable可以將URL中的占位符參數綁定到控制器處理方法的入參中:URL中的{xxx}占位符可以通過@PathVeriable("xxx")綁定到操作方法的入參中。

三.映射請求參數

1.請求處理方法簽名

  • springMVC通過分析處理方法的簽名,將HTTP請求信息綁定到處理方法的相應入參中。
  • SpringMVC對控制器處理方法簽名的限制是很寬松的,幾乎可以按喜歡的任何方式對方法進行簽名。
  • 必要時可以對方法及方法入參標注相應的主鍵(@PathVariable、@RequestParam、@RequestHeader等),SpringMVC框架會將HTTP請求的信息綁定到相應的方法入參中,并根據方法的返回值類型做出相應的后續處理。

2.使用@RequestParam綁定請求參數值。

  • 在處理方法入參處使用@RequestParam可以把請求參數傳遞給請求方法。
    • value:參數名。
    • required:是否必須,默認為true,表示請求參數中必須包含對應的參數,若不存在,將拋出異常。

3.使用@RequestHeader綁定請求頭的屬性值

  • 請求頭包含了若干個屬性,服務器可據此獲知客戶端的信息,通過@RequestHeader即可將請求頭中的屬性值綁定到處理方法的入參中。

4.使用@CookieValue綁定請求參數中的Cookie的值

  • @CookieValue可讓處理方法入參綁定某個cookie值。

5.使用POJO對象綁定請求參數值

  • SpringMVC會按請求參數名和POJO屬性名稱進行自動匹配,自動為該對象填充屬性,支持級聯屬性。

6.使用Servlet API作為入參

  • 使用HttpServletRequest、HttpServletResponse、HttpSession、java.lang.Principal、Locale、InputStream、OutputStream、Reader、Writer

四、處理模型數據

1.SpringMVC提供輸出模型數據的途徑

  • ModelAndView:處理方法返回值類型為ModelAndView時,方法體即可通過該對象添加數據模型。
  • Map及Model:入參為org.springframework.ui.Model、org.springframework.ui.ModelMap或java.util.Map時,處理方法返回時,Map中的數據會自動添加到模型中。
  • @SessionAttributes:將模型中的某個屬性暫存到HttpSession中,以便多個請求之間可以共享這個屬性。
  • @ModelAttribute:方法入參標注該注解后,入參的對象就會放到數據模型中。

2.ModelAndView

  • 控制器處理方法的返回值如果為ModelAndView,則其既包含視圖信息,也包含模型數據信息。

  • 添加模型數據。

    • ModelAndView addObject(String attributeName,Object attributeValue)
    • ModelAndView addAllObject(Map<String,?> modeMap)
  • 設置視圖

    • void setView(View view);
    • void setViewName(String viewName)

3.Map及Model

  • SpringMVC在內部使用了一個org.springframework.ui.Model接口存儲模型數據。
  • 具體步驟:
    • SpringMVC在調用方法前會創建一個隱含的模型對象作為模型數據的存儲容器。
    • 如果方法的入參為Map或Model類型,SpringMVC會將隱含模型的引用傳遞給這些入參。在方法體內,開發者可以通過這個入參對象訪問到模型中的所有數據,也可以向模型中添加新的屬性數據。

4.SessionAttributes

  • 若希望在多個請求之間共用摸個模型屬性數據。則可以在控制器類上標注一個@SessionAttributes,SpringMVC將在模型中對應的屬性暫存到HttpSession中。
  • @SessionAttributes除了可以通過屬性名指定需要放到會話中的屬性外,還可以通過模式屬性的對象類型指定那些模型屬于需要放到會話中。
    • @SessionAttributes(types=User.class)會將隱含模型中所有類型為User.class的屬性添加到會話中。
    • @SessionAttributes(value={"user1","user2"},)會將隱含模型中的名稱為user1和user2的屬性添加到會話中。
      -@SessionAttributes(value{"user1"},types={User.class}) 可以同時進行指定。

5.ModelAttributes

  • 在方法定義上使用@ModelAttributes注解:SpringMVC在調用目標處理方法前,會先逐個調用在方法級別上標注了@ModelAttributes的方法。
  • 在方法的入參使用@ModelAttributes注解:
    • 可以從隱含對象中獲取隱含的模型數據中獲取對象,再將請求參數綁定到對象中,再傳入入參。
    • 將方法入參對象添加到模型中。

6.由@SessionAttributes引發的異常

  • 如果在處理類定義處標準了@SessionAttributes("xxx"),則嘗試從會話中獲取該屬性,并將其賦值給入參,然后再用請求消息填充該入參對象。如果在會話中找不到對應的屬性,就會拋出HttpSessionRequiredException異常。
  • 如果避免,可以在類中通過該屬性名稱的getter方法手動向隱含模型中添加一個名稱為屬性名的模型屬性。

五.視圖和視圖解析器

1.SpringMVC如何解析視圖

image.png

2.視圖和視圖解析器

  • 請求處理方法執行完成后,最終返回一個ModelAndView對象。對應那些返回String,View或ModelMap等類型的處理,SpringMVC也會在內部將它們裝配成一個ModelAndView對象,它包含了邏輯名和模型對象的視圖。
  • SpringMVC借助視圖解析器得到最終的視圖對象,最終的視圖可以是JSP,也可能是Excel、JFreechart等各種表現形式的視圖。
  • 對于最終究竟采用何種視圖對象對模型數據進行渲染。處理器不關心,處理器各種重點聚焦在生模型數據的工作上,從而實現MVC的重復解耦。

3.視圖

  • 視圖的作用是渲染模型數據,將模型里的數據以某種形式呈現個客戶。
  • 為了實現視圖模型和具體實現技術的解耦,Spring在org.springframework.web.servlet包中定義了一個高度抽象的View接口。
  • 視圖對象由視圖解析器負責實例化。由于視圖是無狀態的,所以他們不會有線程安全的問題。

4.常用的視圖實現類

大類 視圖類型 說明
URL視圖解析器 InternalResourceView 將JSP或其它資源封裝成一個視圖,是InternalResourceViewResolver默認使用的視圖實現類
URL視圖解析器 JstlView 如果JSP文件中使用了JSTL國際化標簽的功能,則需要使用該視圖類
文檔視圖 AbstractExcelView excel文檔視圖的抽象類。該視圖基于POI構造excel文檔
文檔視圖 AbstractPdfView PDF文檔視圖的抽象類,該視圖類基于IText構造PDF文檔。
報表視圖 configurableJsperReportsView 使用JasperReports報表技術的視圖
報表視圖 JasperReportsCsvView 使用JasperReports報表技術的視圖
報表視圖 JasperReportsMultiFormatView 使用JasperReports報表技術的視圖
報表視圖 JasperReportsHtmlView 使用JasperReports報表技術的視圖
報表視圖 JasperReportsPdfView 使用JasperReports報表技術的視圖
報表視圖 JasperReportsXlsView 使用JasperReports報表技術的視圖
JSON視圖 MappingJacksonJsonView 將模型數據通過Jackson開源框架的ObjectMapper以JSON方式輸出

5.視圖解析器

  • SpringMVC為邏輯視圖名的解析提供了不同的策略,可以早SpringWEB上下文中配置一種或多種解析策略,并指定他們之間的先后順序。每一種映射策略對應一個具體的視圖解析器實現類。
  • 視圖解析器的作用比較單一:將邏輯視圖解析為一個具體的試圖對象。
  • 所有的視圖解析器都必須實現ViewResolver接口。

6.常用的視圖解析器實現類

大類 視圖類型 說明
解析為Bean的名字 BeanNameViewResolver 將邏輯視圖名解析為一個Bean,Bean的id等于邏輯視圖名。
解析為URL文件 InternalResourceViewResolve 將視圖對象解析為一個URL文件,一般使用該解析器將視圖名映射成為一個保存在WEB-INF目錄下面的程序文件。
解析為URL文件 JasperReportsViewResolver JasperReports是一個基于java的開源報表工具,該解析器將視圖名解析為報表文件對應的URL
模板文件視圖 FreeMarkerResolver 解析基于FreeMarker模板技術的模板文件
模板文件視圖 VelocityViewResolver 解析基于Velocity模板技術的模板文件
模板文件視圖 VelocityLayoutViewResolver 解析基于Velocity模板技術的模板文件
  • 可以選擇使用一種視圖解析器或混用多種視圖解析器
  • 每個視圖解析器都實現了Ordered接口并開發出一個order屬性,可以通過order屬性指定解析器的優先順序,order越小優先級越高。
  • SpringMVC會按照視圖解析器順序的優先順序對邏輯視圖進行解析,知道解析成功并返回視圖對象,否則將拋出ServletException異常。

7.InternalResourceViewResolver

  • JSP是最常見的視圖技術,可以使用InternalResourceViewResolver作為視圖解析器。
  • 若項目中使用了JSTL,則SpringMVC會自動把視圖由InternalResourceView轉為JstlView。
  • 若使用JSTL的fmt標簽需要在SpringMVC的配置文件中配置國際化資源文件。
  • 若希望直接響應通過SpringMVC渲染的頁面,可以使用mvc:view-controller標簽實現。

8.Excel視圖

  • 若希望使用Excel展示數據文件,僅需要擴展SpringMVC提供的AbstractExcelView或AbstractJExcelView即可。實現buildExcelDocument()方法,在方法中使用模型數據對象構建Excel文檔就可以了。
  • AbstractExcelView基于POI API,而AbstractJExcelView是基于JExcelAPI的。
  • 視圖對象需要配置IOC容器中的一個Bean,使用BeanNameViewResolver作為視圖解析器即可。
  • 若希望直接再瀏覽器中直接下載Excel文檔,則可以設置響應頭Content-Disposition的值為attachment;filename=xxx.xls。

9.關于重定向

  • 一般情況下,控制器方法返回字符串類型的值會被當成邏輯視圖名處理。
  • 如果返回的字符串中帶forward:或redirect:前綴時,SpringMVC會對他們進行特殊處理:將forward:和redirect:當成指示符,其后的字符串作為URL來處理。
    • redirect:success.jsp:會完成一個到success.jsp的重定向操作。
    • forward:success.jsp:會完成一個到success.jsp的轉發操作。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,565評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,115評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,577評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,514評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,234評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,621評論 1 326
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,641評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,822評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,380評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,128評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,319評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,879評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,548評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,970評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,229評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,048評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,285評論 2 376

推薦閱讀更多精彩內容

  • 國家電網公司企業標準(Q/GDW)- 面向對象的用電信息數據交換協議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 11,067評論 6 13
  • Swift1> Swift和OC的區別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,125評論 1 32
  • 對于java中的思考的方向,1必須要看前端的頁面,對于前端的頁面基本的邏輯,如果能理解最好,不理解也要知道幾點。 ...
    神尤魯道夫閱讀 827評論 0 0
  • 1、@Controller 在SpringMVC 中,控制器Controller 負責處理由DispatcherS...
    jkian閱讀 1,009評論 5 14
  • 因為畢業。所以沒太畫畫,就把最近畫的一些圖po上來吧~ 希望喜歡畫畫的朋友們能堅持下去~ 我們都會越來越進步! 工...
    阿念_閱讀 427評論 3 3