天天看點

ModelAndView詳解 2016.4.14

ModelAndView

的構造方法有7個。但是它們都是相通的。這裡使用無參構造函數來舉例說明如何構造ModelAndView

執行個體。  

ModelAndView類别就如其名稱所示,是代表了MVC Web程式中Model與View的對象,不過它隻是友善您一次傳回這兩個對象的holder,Model與View兩者仍是分離的概念。

 最簡單的ModelAndView是持有View的名稱傳回,之後View名稱被viewresolver,也就是實作org.springframework.web.servlet.View接口的執行個體解析,例如InternalResourceView或JstlView等等:

ModelAndView(String viewName)

 如果您要傳回Model對象,則可以使用Map來收集這些Model對象,然後設定給ModelAndView,使用下面這個版本的ModelAndView:

ModelAndView(String viewName, Map model)

 Map對象中設定好key與value值,之後可以在視圖中取出,如果您隻是要傳回一個Model對象,則可以使用下面這個ModelAndView版本:

ModelAndView(String viewName, String modelName, Object modelObject)

 藉由modelName,您可以在視圖中取出Model并顯示。

 ModelAndView類别提供實作View接口的對象來作View的參數:

ModelAndView(View view)

ModelAndView(View view, Map model)

ModelAndView(View view, String modelName, Object modelObject)

 一個例子是org.springframework.web.servlet.view.RedirectView,ModelAndView預設是使用forward來轉發請求結果至視圖,使用RedirectView的話,則會使用redirect将請求重導至視圖,例如:

public ModelAndView handleRequest(....) … {

    ....

    return new ModelAndView(new RedirectView(this.getViewPage()));

}

....

 在這邊,viewPage的位址是從伺服器網頁根目錄開始指定,而不是Web應用程式的根目錄,是以您的getViewPage()傳回的位址必須像是/springapp/pages/index.htm這樣的位址,其中springapp是您的Web應用程式目錄。

 使用forward的話,網址列上并不會出現被轉發的目标位址,而且forward是在Web應用程式之内進行,可以通路Web應用程式的隐藏目錄,像是WEB-INF,然而forward隻能在Web應用程式中進行,不能指定至其它的Web應用程式位址。

 使用redirect的話,是要求用戶端浏覽器重新發出一個指定的請求位址,是以網址列上會出現被重導的目錄位址,重導的請求是由浏覽器發出,是以不能通路Web應用程式中的隐藏目錄,像是WEB-INF,然而重導是重新要求一個網頁,是以可以指定至其它的Web應用程式位址。

 DispatcherServlet會根據傳回的ModelAndView來解析View名稱,并處理給予的Model。View名稱的解析是委托給實作org.springframework.web.servlet.ViewResolver接口的執行個體,ViewResolver接口定義如下:

public interface ViewResolver {

    public view resolveViewName(String, Locale locale) throws ServletException;

}

 ViewResolver的一個執行個體是InternalResourceViewResolver,名稱解析完之後,實際的View繪制與Model轉換處理是交給實作org.springframework.web.servlet.View的執行個體,View接口如下:

public interface View {

    public void render(Map model, HttpServletResquest resquest, HttpServletResponse response) throws ServletException, IOException;

}

 View的實作之前用過org.springframework.web.servlet.view.InternalResourceView,另外也還有JstlView、TilesView、VelocityView等等的實作,分别進行不同的表現展處理。

ModelAndView()

    這個構造方法構造出來的ModelAndView

不能直接使用,應為它沒有指定view,也沒有綁定對應的model對象。當然,model對象不是必須的,但是view确實必須的。

    用這個構造方法構造的執行個體主要用來在以後往其中加view設定和model對象。

    給ModelAndView

執行個體設定view的方法有兩

個:setViewName(String viewName) 和 setView(View view)。前者是使用view

name,後者是使用預先構造好的View對象。其中前者比較常用。事實上View是一個接口,而不是一個可以構造的具體類,我們隻能通過其他途徑來擷取

View的執行個體。對于view

name,它既可以是jsp的名字,也可以是tiles定義的名字,取決于使用的ViewNameResolver如何了解這個view name。

    如何擷取View的執行個體以後再研究。

而對應如何給ModelAndView

執行個體設定model則比較複雜。有三個方法可以使用:

addObject(Object modelObject)

addObject(String modelName, Object modelObject)

addAllObjects(Map modelMap)

ModelAndView

可以接收Object類型的對象,ModelAndView

将它視為其衆多model中的一個。當使用Object類型的對象的時候,必須指定一個名字。ModelAndView

也可以接收沒有明顯名字的對象,原因在于ModelAndView

将調用spring自己定義的Conventions 類的.getVariableName()方法來為這個model生成一個名字。顯然,對model而言,名字是必須的。

Conventions.getVariableName()生成名字的規則是使用對象的類名的小寫模式來作model名字。當這個model是集合或數組的時候,使用集合的第一個元素的類名加s來作model的名字。

ModelAndView

也可以接收Map類型的對象,ModelAndView

将這個Map中的元素視為model,而不是把這個Map本身視為model。但是其他的集合類可以用本身作為model對象。

實際上,ModelAndView

對model的支援來自于類ModelMap,這個類繼承自HashMap。

完整的例子

Java代碼  

ModelAndView詳解 2016.4.14
  1. <span style="font-size: small;">public ModelAndView handleRequestInternal(  
  2.         HttpServletRequest request,  
  3.         HttpServletResponse response) throws Exception {  
  4. ModelAndView mav = new ModelAndView("hello");//執行個體化一個VIew的ModelAndView執行個體  
  5. mav.addObject("message", "Hello World!");//添加一個帶名的model對象  
  6.         return mav;          
  7. }  
  8. </span>