ModelAndView的使用方法

當控制器處理完請求時,通常會將包含視圖名稱或視圖對象以及一些模型屬性的ModelAndView對象返回到DispatcherServlet。

因此,經常需要在控制器中構造ModelAndView對象。ModelAndView類提供了幾個重載的構造器和一些方便的方法,

讓你可以根據自己的喜好來構造ModelAndView對象。這些構造器和方法以類似的方式支持視圖名稱和視圖對象。

當你只有一個模型屬性要返回時,可以在構造器中指定該屬性來構造ModelAndView對象


在上篇的基礎上,只修改Login類

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. package com.itmyhome;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5. import java.util.List;  
  6. import java.util.Map;  
  7.   
  8. import org.springframework.stereotype.Controller;  
  9. import org.springframework.web.bind.annotation.RequestMapping;  
  10. import org.springframework.web.servlet.ModelAndView;  
  11.   
  12. @Controller  
  13. public class Login {  
  14.   
  15.     @RequestMapping(value="login")  
  16.     public ModelAndView login(){  
  17.         ModelAndView mav = new ModelAndView();  
  18.         mav.setViewName("welcome"); //返回的文件名  
  19.           
  20.         mav.addObject("message","hello kitty");  
  21.           
  22.         //List  
  23.         List<String> list = new ArrayList<String>();  
  24.         list.add("java");  
  25.         list.add("c++");  
  26.         list.add("oracle");  
  27.         mav.addObject("bookList", list);  
  28.           
  29.         //Map  
  30.         Map<String,String> map = new HashMap<String,String>();  
  31.         map.put("zhangsan""北京");  
  32.         map.put("lisi""上海");  
  33.         map.put("wangwu""深圳");  
  34.         mav.addObject("map",map);  
  35.           
  36.         return mav;  
  37.     }  
  38. }  

亦或如下方法來構建你的ModelAndView對象

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. @RequestMapping(value="logout")  
  2. public ModelAndView logout(){  
  3.     String message = "歡迎下次光臨!";  
  4.     return new ModelAndView("logout","message",message);  
  5. }  

然後修改welcome.jsp輸出數據

遍歷集合可使用jstl表達式,需在jsp中引入頭文件

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>  
lib下導入jstl.jar和standard.jar

首先這兩個jar在哪裏可以找到,當然可以在網上下載。

另外在tomcat下面就有,在\webapps\examples\WEB-INF\lib

前提是你還沒有把webapps下面的一些無用項目刪掉。


welcome.jsp

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <body>  
  2.    <!-- 輸出普通字符 -->  
  3.    ${message } <br/>  
  4.    <!-- 輸出List -->  
  5.    <p>書籍列表</p>  
  6.    <c:forEach items="${bookList}" var="node">  
  7.         <c:out value="${node}"></c:out>  
  8.    </c:forEach>  
  9.    <br/>  
  10.    <br/>  
  11.      
  12.    <!-- 輸出Map -->  
  13.    <c:forEach items="${map}" var="node">  
  14.         姓名:<c:out value="${node.key}"></c:out>  
  15.         住址:<c:out value="${node.value}"></c:out>  
  16.         <br/>  
  17.    </c:forEach>  
  18. </body>  

結果如圖:




ModelAndView詳解



ModelAndView

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

實例。   
ModelAndView類別就如其名稱所示,是代表了MVC Web程序中Model與View的對象,不過它只是方便您一次返回這兩個對象的holder,Model與View兩者仍是分離的概念。 
  最簡單的ModelAndView是持有View的名稱返回,之後View名稱被view resolver,也就是實作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代碼  收藏代碼
  1. <span style="font-size: small;">public ModelAndView handleRequestInternal(  
  2.         HttpServletRequest request,  
  3.         HttpServletResponse response) throws Exception {  
  4.           
  5.   
  6. ModelAndView mav = new ModelAndView("hello");//實例化一個VIew的ModelAndView實例  
  7.   
  8. mav.addObject("message""Hello World!");//添加一個帶名的model對象  
  9.   
  10.   
  11.         return mav;          
  12.       
  13.   
  14. }  
  15. </span>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章