SpringMVC中的Model和ModelAndView详解

2022-08-07 10:55:44

原文链接:

0.前言

1.Model是什么?

model是”模型“的意思,是MVC架构中的”M“部分,是用来传输数据的。

2.ModelAndView是什么?

如果翻译过来就是”模型和视图“,可以理解成MVC架构中的”M“和”V“,其中包含”Model“和”view“两部分,主要功能是:

设置转向地址
将底层获取的数据进行存储(或者封装)
最后将数据传递给View
区别?

1.Model只是用来传输数据的,并不会进行业务的寻址。ModelAndView 却是可以进行业务寻址的,就是设置对应的要请求的静态文件,这里的静态文件指的是类似jsp的文件。Model是每次请求中都存在的默认参数,利用其addAttribute()方法即可将服务器的值传递到jsp页面中;ModelAndView包含model和view两部分,使用时需要自己实例化,利用ModelMap用来传值,也可以设置view的名称。

2.Model是每一次请求可以自动创建,但是ModelAndView 是需要我们自己去new的。

1.model的使用

查看Model的源码发现,里面比较重要的就是前4个。

package org.springframework.ui;import java.util.Collection;import java.util.Map;import org.springframework.lang.Nullable;/**
 * Java-5-specific interface that defines a holder for model attributes.
 * Primarily designed for adding attributes to the model.
 * Allows for accessing the overall model as a {@code java.util.Map}.
 *
 * @author Juergen Hoeller
 * @since 2.5.1
 */publicinterfaceModel{/**
     * Add the supplied attribute under the supplied name.
     * @param attributeName the name of the model attribute (never {@code null})
     * @param attributeValue the model attribute value (can be {@code null})
     */
    ModeladdAttribute(String attributeName,@Nullable Object attributeValue);/**
     * Add the supplied attribute to this {@code Map} using a
     * {@link org.springframework.core.Conventions#getVariableName generated name}.
     * <p><i>Note: Empty {@link java.util.Collection Collections} are not added to
     * the model when using this method because we cannot correctly determine
     * the true convention name. View code should check for {@code null} rather
     * than for empty collections as is already done by JSTL tags.</i>
     * @param attributeValue the model attribute value (never {@code null})
     */
    ModeladdAttribute(Object attributeValue);/**
     * Copy all attributes in the supplied {@code Collection} into this
     * {@code Map}, using attribute name generation for each element.
     * @see #addAttribute(Object)
     */
    ModeladdAllAttributes(Collection<?> attributeValues);/**
     * Copy all attributes in the supplied {@code Map} into this {@code Map}.
     * @see #addAttribute(String, Object)
     */
    ModeladdAllAttributes(Map<String,?> attributes);/**
     * Copy all attributes in the supplied {@code Map} into this {@code Map},
     * with existing objects of the same name taking precedence (i.e. not getting
     * replaced).
     */
    ModelmergeAttributes(Map<String,?> attributes);/**
     * Does this model contain an attribute of the given name?
     * @param attributeName the name of the model attribute (never {@code null})
     * @return whether this model contains a corresponding attribute
     */booleancontainsAttribute(String attributeName);/**
     * Return the attribute value for the given name, if any.
     * @param attributeName the name of the model attribute (never {@code null})
     * @return the corresponding attribute value, or {@code null} if none
     * @since 5.2
     */@Nullable
    ObjectgetAttribute(String attributeName);/**
     * Return the current set of model attributes as a Map.
     */
    Map<String, Object>asMap();}

Model addAttribute(String attributeName, @Nullable Object attributeValue)
Model addAttribute(Object attributeValue);
Model addAllAttributes(Collection<?> attributeValues);
Model addAllAttributes(Map<String, ?> attributes);
具体用法1:返回一个字符

Controller层的写法

package com.cat.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;/*
 * controller 负责提供访问应用程序的行为,通常通过接口定义或者注解定义两种方法实现。
 * 控制器负责解析用户的请求并将其转换为一个模型。
 * */@Controller//代表这个类会被spring接管,被这个注解的类中所有方法,如果返回值是string,并且有具体的页面可以跳转,那么就会被视图解析器解析publicclassIndexController{@RequestMapping("/hello")//意为请求 localhost:8080/hellopublic Stringhello(Model model){//封装数据(向模型中添加数据,可以jsp页面直接取出并渲染)
        model.addAttribute("name","张三");
        model.addAttribute("sex","男");
        model.addAttribute("age",23);
        System.out.println(model);//会被视图解析器处理return"hello";//返回到哪个页面}}

jsp写法(注意和路径对应)

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>Title</title></head><body>
hello.jsp页面<p>姓名:${name}</p><p>性别:${sex}</p><p>年龄:${age}</p></body></html>

在这里插入图片描述
如果出现上面这种不正常的情况,请点击这里。

正常情况如下所示:
在这里插入图片描述
具体用法2:返回一个对象

model方法是可以返回一个对象的。我们创建一个对象在这里插入图片描述
Person实体类,至少要加上get方法。不然前端取不到数据

package com.cat.domain;publicclassPerson{public  String name;public  String sex;publicint age;public StringgetName(){return name;}publicvoidsetName(String name){this.name= name;}public StringgetSex(){return sex;}publicvoidsetSex(String sex){this.sex= sex;}publicintgetAge(){return age;}publicvoidsetAge(int age){this.age= age;}@Overridepublic StringtoString(){return"Person{"+"name='"+ name+'\''+", sex='"+ sex+'\''+", age="+ age+'}';}}

在这里插入图片描述
IndexController代码改成下面这样。

package com.cat.controller;import com.cat.domain.Person;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;@Controller@RequestMappingpublicclassIndexController{@RequestMapping("/hello")public Stringhello(Model model){
        Person person=newPerson();
        person.name="张三";
        person.age=16;
        person.sex="男";
        System.out.println(person);
        model.addAttribute("person",person);return"hello";}}

hello.jsp改成下面这样子。

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>Title</title></head><body>
hello.jsp页面<p>姓名:${person.name}</p><p>性别:${person.sex}</p><p>年龄:${person.age}</p></body></html>

页面重新请求后变成下面样子说明请求成功

在这里插入图片描述
返回map和collection类型暂时不做演示。

2. ModelAndView

ModelAndView有的方法和Model很类似,一共有下面这些方法。

构造方法:

ModelAndView()  //默认构造函数豆式的用法:填充bean的属性,而不是将在构造函数中的参数。
ModelAndView(String viewName)  //方便的构造时,有没有模型数据暴露。
ModelAndView(String viewName, Map model)  //给出创建一个视图名称和模型新的ModelAndView。
ModelAndView(String viewName, String modelName, Object modelObject)  //方便的构造采取单一的模式对象。
ModelAndView(View view)   //构造方便在没有模型数据暴露。
ModelAndView(View view, Map model)  //创建给定一个视图对象和模型,新的ModelAndView。
ModelAndView(View view, String modelName, Object modelObject)   //方便的构造采取单一的模式对象。

类方法

ModelAndView  addAllObjects(Map modelMap)  //添加包含在所提供的地图模型中的所有条目。
ModelAndView  addObject(Object modelObject)  //添加对象使用的参数名称生成模型。
ModelAndView  addObject(String modelName,ObjectmodelObject)  //对象添加到模型中。
void  clear()  //清除此ModelAndView对象的状态。
Map  getModel()  //返回的模型图。
protectedMap  getModelInternal()  //返回的模型图。
ModelMap  getModelMap()  //返回底层ModelMap实例(从不为null)。
View  getView()  //返回View对象,或者为null,如果我们使用的视图名称由通过一个ViewResolverDispatcherServlet会得到解决。
String  getViewName()  //返回视图名称由DispatcherServlet的解决,通过一个ViewResolver,或空,如果我们使用的视图对象。
boolean  hasView()  //指示此与否的ModelAndView有一个观点,无论是作为一个视图名称或作为直接查看实例。
boolean  isEmpty()  //返回此ModelAndView对象是否为空,即是否不持有任何意见,不包含模型。
boolean  isReference()  //返回,我们是否使用视图的参考,i.e.
void  setView(Viewview)  //设置此ModelAndView的视图对象。
void  setViewName(StringviewName)  //此ModelAndView的设置视图名称,由通过一个ViewResolverDispatcherServlet会得到解决。
String  toString()  //返回这个模型和视图的诊断信息。
boolean  wasCleared()??  //返回此ModelAndView对象是否为空的调用的结果,以清除(),即是否不持有任何意见,不包含模型。

在Controller中添加一个新的方法。

package com.cat.controller;import com.cat.domain.Person;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;@Controller@RequestMappingpublicclassIndexController{//    @RequestMapping("/hello")//    public String hello(Model model){//        Person person =new Person();//        person.name="张三";//        person.age=16;//        person.sex="男";//        System.out.println(person);//        model.addAttribute("person",person);//        return "hello";//    }@RequestMapping("/hello2")public ModelAndViewhello(){
 
            ModelAndView modelAndView=newModelAndView();
            modelAndView.setViewName("hello");//返回到那个文件
            modelAndView.addObject("name","派大星");
            modelAndView.addObject("sex","男");
            modelAndView.addObject("age",53);
            System.out.println(modelAndView);return modelAndView;}}

hello.jsp改成

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>Title</title></head><body>
hello.jsp页面<p>姓名:${name}</p><p>性别:${sex}</p><p>年龄:${age}</p></body></html>

请求新的地址后发现数据没有问题。

在这里插入图片描述
同理,ModelAndView也可以返回一个对象。这里就不做演示了。

  • 作者:城南蝈蝈
  • 原文链接:https://blog.csdn.net/baidu_32523857/article/details/109965018
    更新时间:2022-08-07 10:55:44