我的理解:View爲服務器上的某個文件容器,能夠爲JSP,FTL等動態頁面文件,甚至是媒體文件等等,單單是一個文件。Model的做用是存儲動態頁面屬性,動態頁面文件即View能夠在Model中獲取動態數據,這樣就實現了View和Model分離的目的。接下來分別對這三個作一下說明。html
1、首先是View:View接口在org.springframework.web.servlet.View包內。核心方法:java
一、getContentType()獲取當前view的ContentType(),同http請求中的ContenType()是同樣的做用。web
二、render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)。spring
render(使成爲;遞交;給予;表達;渲染)Dispatcher(發報機; 收發; 調度;調度員 )服務器
根據參數就能夠知道,這個是爲視圖綁定Request,Response和Model的方法。session
三、View的一個實現類AbstractView,其中有方法:架構
(s&g)BeanName(String beanName) (s&g)ContentType(String contentType) (s&g)RequestContextAttribute(String requestContextAttribute) setAttributesCSV(String propString) setAttributes(java.util.Properties attributes) (s&g)AttributesMap(Map<String, ?> attributes) addStaticAttribute(String name, Object value) Map<String, Object> getStaticAttributes() (s&i)ExposePathVariables(boolean exposePathVariables) Map<String, Object> createMergedOutputModel(Map<String, ?> model, HttpServletRequest request,HttpServletResponse response) RequestContext createRequestContext(HttpServletRequest request, HttpServletResponse response, Map<String, Object> model) renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) exposeModelAsRequestAttributes(Map<String, Object> model, HttpServletRequest request) writeToResponse(HttpServletResponse response, ByteArrayOutputStream baos) setResponseContentType(HttpServletRequest request, HttpServletResponse response)
其中後面的是與組合Model和Response的方法。app
根據源碼可知,View其中的staticAttributes其實最終仍是給了Model,經過mergedModel.putAll(pathVars);jsp
四、view的子接口SmartView,惟一一個方法isRedirectView,用於標記是不是重定向View。url
RedirectView實現SmartView接口,繼承AbstractUrlBasedView,AbstractUrlBasedView又繼承自AbstractView,就是一個基本的Url的View,內部方法:
包含一個url屬性,標記重定向到哪一個url,還有一系列和http相關的協議參數,如encodingScheme,statusCode,contextRelative等等,以及其餘實現View中的方法。
2、model,model相對簡單,就是一些屬性的鍵值對而已。merge(融合,整合)
一、方法有:
Model addAttribute(String attributeName, Object attributeValue);
Model addAttribute(Object attributeValue);
Model addAllAttributes(Collection<?> attributeValues);
Model addAllAttributes(Map<String, ?> attributes);
Model mergeAttributes(Map<String, ?> attributes);
boolean containsAttribute(String attributeName);
Map<String, Object> asMap();
其中只加值的時候,屬性名經過org.springframework.core.Conventions的getVariableName生成。
該接口的實現類爲ExtendedModelMap,特殊的,ExtendedModelMap繼承了ModelMap類,而ModelMap實際上是繼承了LinkedHashMap<String, Object>類。
ExtendedModelMap的全部方法,都在ModelMap中實現了。
二、Model有個子接口RedirectAttributes,用於設置重定向的屬性。比Model裏面多了一個Model,RedirectAttributes中實際上是有兩個Map的。
RedirectAttributes addFlashAttribute(String attributeName, Object attributeValue);
RedirectAttributes addFlashAttribute(Object attributeValue);
Map<String, ?> getFlashAttributes();
他的實現類爲RedirectAttributesModelMap,一樣繼承自ModelMap,內部成員有DataBinder數據用於數據綁定,flashAttributes則是另外一個Map,保存着重定向的屬性。
該類構造時直接傳入一個數據綁定器,可爲null,RedirectAttributesModelMap(org.springframework.validation.DataBinderdataBinder)
轉發與重定向區別可參考(http://www.cnblogs.com/shenliang123/archive/2011/10/27/2226892.html)
3、ModelAndView,顧名思義,就是整合了Model和View,經常使用於動態頁面也是,一個後臺網頁就包含這兩部分,前臺就是基本的html代碼。
內部包含一個Object類型的view,一個ModelMap類型的model,還有一個標記是否被clear()方法清除的cleared變量。
構造方法:ModelAndView()
ModelAndView(String viewName)
ModelAndView(View view)
ModelAndView(String viewName, Map<String, ?> model)
ModelAndView(View view, Map<String, ?> model)
ModelAndView(String viewName, String modelName, Object modelObject)
ModelAndView(View view, String modelName, Object modelObject)
(s&g)ViewName
(s&g)View
boolean hasView
isReference:若是view instanceof String則爲true
Map<String, Object> getModelInternal()
ModelMap getModelMap()
Map<String, Object> getModel()
ModelAndView addObject(String attributeName, Object attributeValue)
ModelAndView addObject(Object attributeValue)
ModelAndView addAllObjects(Map<String, ?> modelMap)
void clear():清除其中的view和model
由此能夠看出,構造View能夠直接使用字符串,至關於路徑引用View
4、最後,這幾個實際中究竟是在哪使用,如何使用的呢?
Spring架構中,他是使用在@Controller層中的@RequestMapping註解方法中的,該註解方法有如下幾種:
返回值能夠有:ModelAndView, Model, ModelMap, Map,View, String, void
參數能夠任意多,參數能夠爲POJO對象,能夠爲PO,能夠爲Array,List,String等等,只要能和Request中參數名一致,Spring就會自動綁定到特定的數據類型中,很是方便。其中有三個特殊類型的參數:HttpServletRequest request, HttpServletResponse response, Model model,其中第一個爲當前網頁發過來的請求,第二個是要返回的形影,第三個則是當前網頁發過來的model參數集以及要設置給返回視圖的參數集Model。
注:參數中的Model也能夠變爲一樣的Map,或者ModelMap,三者等價。
來看看不一樣類型的返回值表明什麼吧。
一、ModelAndView
@RequestMapping("/show1") public ModelAndView show1(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView mav = new ModelAndView("/demo2/show"); mav.addObject("account", "account -1"); return mav; }
這種是直接把View和Model封裝好返回給Spring,Spring再交給動態網頁架構去返回靜態html給客戶端。
經過ModelAndView構造方法能夠指定返回的頁面名稱,也能夠經過setViewName()方法跳轉到指定的頁面 ,使用addObject()設置須要返回的值,addObject()有幾個不一樣參數的方法,能夠默認和指定返回對象的名字。
二、Model=ModelMap=Map,是同樣的
@RequestMapping("/demo2/show") public Map<String, String> getMap() { Map<String, String> map = new HashMap<String, String>(); map.put("key1", "value-1"); map.put("key2", "value-2"); return map; }
至關於把Map返回給當前網頁。在jsp頁面中可直經過${key1}得到到值, map.put()至關於request.setAttribute方法。key值包括 - . 時會有問題.
三、View 能夠返回pdf excel等各類View,此時該View的Model能夠在方法傳遞的參數中設置。只需在方法中加上參數Model model,對該model設置屬性,都會反饋到該View中。
四、String,其實也是View,該View是urlView,指定返回的視圖頁面名稱,結合設置的返回地址路徑加上頁面名稱後綴便可訪問到。
@RequestMapping(value = "/something", method = RequestMethod.GET) @ResponseBody public String helloWorld() { return "Hello World"; }
注意:若是方法聲明瞭註解@ResponseBody ,則會直接將返回值輸出到頁面。上面的結果會將文本"Hello World "直接寫到http響應流。
若沒有註解@ResponseBody,則對應的邏輯視圖名爲「center」,URL= prefix前綴+視圖名稱 +suffix後綴組成。若是以絕對路徑書寫,則在applicationContext路徑爲根的目錄下尋找View。
@RequestMapping("/welcome") public String welcomeHandler() { return "center"; }
最後一個特殊的爲void,響應的視圖頁面對應爲訪問地址。
@RequestMapping("/welcome") public void welcomeHandler() {}
此例對應的邏輯視圖名爲"welcome"。
PS:1.使用 String 做爲請求處理方法的返回值類型是比較通用的方法,這樣返回的邏輯視圖名不會和請求 URL 綁定,具備很大的靈活性,而模型數據又能夠經過 ModelMap 控制。
2.使用void,map,Model 時,返回對應的邏輯視圖名稱真實url爲:prefix前綴+視圖名稱 +suffix後綴組成。
3.使用String,ModelAndView返回視圖名稱能夠不受請求的url綁定,ModelAndView能夠設置返回的視圖名稱。
補充:
Model model,HttpServletRequest request, ModelMap map聲明變量,均可以賦屬性和屬性值,具體先引用誰呢?
request.getSession().setAttribute("test", "haiwei2Session");
request.setAttribute("test", "haiwei1request");
map.addAttribute("test", "haiweiModelMap");
model.addAttribute("test", "haiweiModel");
經過${test}取值,優先取Model和ModelMap的,Model和ModelMap是同一個東西,誰最後賦值的就取誰的,而後是request,最後是從session中獲取。
更多內容參考:http://www.360doc.com/content/14/0309/19/834950_359081989.shtml