原文链接:
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的。
查看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
*/
public interface Model {
/**
* 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})
*/
Model addAttribute(String attributeName, @Nullable Object attributeValue);
/**
* Add the supplied attribute to this {@code Map} using a
* {@link org.springframework.core.Conventions#getVariableName generated name}.
* 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.
* @param attributeValue the model attribute value (never {@code null})
*/
Model addAttribute(Object attributeValue);
/**
* Copy all attributes in the supplied {@code Collection} into this
* {@code Map}, using attribute name generation for each element.
* @see #addAttribute(Object)
*/
Model addAllAttributes(Collection<?> attributeValues);
/**
* Copy all attributes in the supplied {@code Map} into this {@code Map}.
* @see #addAttribute(String, Object)
*/
Model addAllAttributes(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).
*/
Model mergeAttributes(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
*/
boolean containsAttribute(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
Object getAttribute(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
具体用法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,并且有具体的页面可以跳转,那么就会被视图解析器解析
public class IndexController {
@RequestMapping("/hello") //意为请求 localhost:8080/hello
public String hello(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>
model方法是可以返回一个对象的。我们创建一个对象
Person实体类,至少要加上get方法。不然前端取不到数据
package com.cat.domain;
public class Person {
public String name;
public String sex;
public int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}
}
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
@RequestMapping
public class IndexController {
@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";
}
}
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>
页面重新请求后变成下面样子说明请求成功
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
@RequestMapping
public class IndexController {
// @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 ModelAndView hello(){
ModelAndView modelAndView = new ModelAndView();
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>
请求新的地址后发现数据没有问题。