zoukankan      html  css  js  c++  java
  • Spring MVC:Model、View、ModelAndView

    个人理解:View为服务器上的某个文件容器,可以为JSP,FTL等动态页面文件,甚至是媒体文件等等,单单是一个文件。Model的作用是存储动态页面属性,动态页面文件即View可以在Model中获取动态数据,这样就实现了View和Model分离的目的。接下来分别对这三个做一下说明。

    一、首先是View:View接口在org.springframework.web.servlet.View包内。核心方法:

      1、getContentType()获取当前view的ContentType(),同http请求中的ContenType()是一样的作用。

      2、render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)。

      render(使成为;递交;给予;表达;渲染)Dispatcher(发报机; 收发; 调度;调度员 )

      根据参数就可以知道,这个是为视图绑定Request,Response和Model的方法。

      3、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的方法。

      根据源码可知,View其中的staticAttributes其实最终还是给了Model,通过mergedModel.putAll(pathVars);

      4、view的子接口SmartView,唯一一个方法isRedirectView,用于标记是否是重定向View。

      RedirectView实现SmartView接口,继承AbstractUrlBasedView,AbstractUrlBasedView又继承自AbstractView,就是一个基本的Url的View,内部方法:

      包含一个url属性,标记重定向到哪个url,还有一系列和http相关的协议参数,如encodingScheme,statusCode,contextRelative等等,以及其他实现View中的方法。

     二、model,model相对简单,就是一些属性的键值对而已。merge(融合,整合)

      1、方法有:

      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中实现了。

      2、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)

    三、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

     四、最后,这几个实际中到底是在哪使用,如何使用的呢?

      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,三者等价。

      来看看不同类型的返回值代表什么吧。

      1、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()有几个不同参数的方法,可以默认和指定返回对象的名字。
      2、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值包括 - . 时会有问题.

      3、View 可以返回pdf excel等各种View,此时该View的Model可以在方法传递的参数中设置。只需在方法中加上参数Model model,对该model设置属性,都会反馈到该View中。

      4、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

  • 相关阅读:
    swift 学习笔记
    collection view 开发笔记
    代码片段
    childViewController 小计
    iOS 二维码扫描
    statusbarhidden stuff 状态栏的各种特性
    AFNetworking 3.0 断点续传 使用记录
    scrollview 图片放大 捏合 瓦片地图 相关注意事项
    iOS 9 强制横屏
    简单的JS运动封装实例---侧栏分享到
  • 原文地址:https://www.cnblogs.com/guangshan/p/4438130.html
Copyright © 2011-2022 走看看