在了解这三者之前,需要知道一点:SpringMVC在调用方法前会创建一个隐含的数据模型,作为模型数据的存储容器, 成为”隐含模型”。
也就是说在每一次的前后台请求的时候会随带这一个背包,不管你用没有,这个背包确实是存在的,用来盛放我们请求交互传递的值;关于这一点,spring里面有一个注解:
@ModelAttribute :被该注解修饰的方法,会在每一次请求时优先执行,用于接收前台jsp页面传入的参数
例子:

@Controller
public class User1Controller{private static final Log logger = LogFactory.getLog(User1Controller.class);// @ModelAttribute修饰的方法会先于login调用,该方法用于接收前台jsp页面传入的参数@ModelAttributepublic void userModel(String loginname,String password,Model model){logger.info("userModel");// 创建User对象存储jsp页面传入的参数User2 user = new User2();user.setLoginname(loginname);user.setPassword(password);// 将User对象添加到Model当中model.addAttribute("user", user);}@RequestMapping(value="/login1")public String login(Model model){logger.info("login");// 从Model当中取出之前存入的名为user的对象User2 user = (User2) model.asMap().get("user");System.out.println(user);// 设置user对象的username属性user.setUsername("测试");return "result1";}

在前端向后台请求时,spring会自动创建Model与ModelMap实例,我们只需拿来使用即可;

无论是Mode还是ModelMap底层都是使用BindingAwareModelMap,所以两者基本没什么区别;
我们可以简单看一下两者区别:

①Model

Model是一个接口,它的实现类为ExtendedModelMap,继承ModelMap类

public class ExtendedModelMap extends ModelMap implements Model

②ModelMap

ModelMap继承LinkedHashMap,spring框架自动创建实例并作为controller的入参,用户无需自己创建

public class ModelMap extends LinkedHashMap

而是对于ModelAndView顾名思义,ModelAndView指模型和视图的集合,既包含模型 又包含视图;ModelAndView的实例是开发者自己手动创建的,这也是和ModelMap主要不同点之一;ModelAndView其实就是两个作用,一个是指定返回页面,另一个是在返回页面的同时添加属性; 它的源码:

public class ModelAndView {  /** View instance or view name String */  private Object view  //该属性用来存储返回的视图信息
/** Model Map */
private ModelMap model;//<span style="color: rgb(0, 130, 0); font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">该属性用来存储处理后的结果数据</span>  /** * Indicates whether or not this instance has been cleared with a call to {@link #clear()}. */
private boolean cleared = false;  /** * Default constructor for bean-style usage: populating bean * properties instead of passing in constructor arguments. * @see #setView(View) * @see #setViewName(String) */
public ModelAndView() {
}  /** * Convenient constructor when there is no model data to expose. * Can also be used in conjunction with <code>addObject</code>. * @param viewName name of the View to render, to be resolved * by the DispatcherServlet's ViewResolver * @see #addObject */
public ModelAndView(String viewName) {  this.view = viewName;
}  /** * Convenient constructor when there is no model data to expose. * Can also be used in conjunction with <code>addObject</code>. * @param view View object to render * @see #addObject */
public ModelAndView(View view) {  this.view = view;
}  /** * Creates new ModelAndView given a view name and a model. * @param viewName name of the View to render, to be resolved * by the DispatcherServlet's ViewResolver * @param model Map of model names (Strings) to model objects * (Objects). Model entries may not be <code>null</code>, but the * model Map may be <code>null</code> if there is no model data. */
public ModelAndView(String viewName, Map<String, ?> model) {  this.view = viewName;  if (model != null) {  getModelMap().addAllAttributes(model);  }
}  /** * Creates new ModelAndView given a View object and a model. * <emphasis>Note: the supplied model data is copied into the internal * storage of this class. You should not consider to modify the supplied * Map after supplying it to this class</emphasis> * @param view View object to render * @param model Map of model names (Strings) to model objects * (Objects). Model entries may not be <code>null</code>, but the * model Map may be <code>null</code> if there is no model data. */
public ModelAndView(View view, Map<String, ?> model) {  this.view = view;  if (model != null) {  getModelMap().addAllAttributes(model);  }
}  /** * Convenient constructor to take a single model object. * @param viewName name of the View to render, to be resolved * by the DispatcherServlet's ViewResolver * @param modelName name of the single entry in the model * @param modelObject the single model object */
public ModelAndView(String viewName, String modelName, Object modelObject) {  this.view = viewName;  addObject(modelName, modelObject);
}  /** * Convenient constructor to take a single model object. * @param view View object to render * @param modelName name of the single entry in the model * @param modelObject the single model object */
public ModelAndView(View view, String modelName, Object modelObject) {  this.view = view;  addObject(modelName, modelObject);
}  /** * Set a view name for this ModelAndView, to be resolved by the * DispatcherServlet via a ViewResolver. Will override any * pre-existing view name or View. */
public void setViewName(String viewName) {  this.view = viewName;
}  /** * Return the view name to be resolved by the DispatcherServlet * via a ViewResolver, or <code>null</code> if we are using a View object. */
public String getViewName() {  return (this.view instanceof String ? (String) this.view : null);
}  /** * Set a View object for this ModelAndView. Will override any * pre-existing view name or View. */
public void setView(View view) {  this.view = view;
}  /** * Return the View object, or <code>null</code> if we are using a view name * to be resolved by the DispatcherServlet via a ViewResolver. */
public View getView() {  return (this.view instanceof View ? (View) this.view : null);
}  /** * Indicate whether or not this <code>ModelAndView</code> has a view, either * as a view name or as a direct {@link View} instance. */
public boolean hasView() {  return (this.view != null);
}  /** * Return whether we use a view reference, i.e. <code>true</code> * if the view has been specified via a name to be resolved by the * DispatcherServlet via a ViewResolver. */
public boolean isReference() {  return (this.view instanceof String);
}  /** * Return the model map. May return <code>null</code>. * Called by DispatcherServlet for evaluation of the model. */
protected Map<String, Object> getModelInternal() {  return this.model;
}  /** * Return the underlying <code>ModelMap</code> instance (never <code>null</code>). */
public ModelMap getModelMap() {  if (this.model == null) {  this.model = new ModelMap();  }  return this.model;
}  /** * Return the model map. Never returns <code>null</code>. * To be called by application code for modifying the model. */
public Map<String, Object> getModel() {  return getModelMap();
}  /** * Add an attribute to the model. * @param attributeName name of the object to add to the model * @param attributeValue object to add to the model (never <code>null</code>) * @see ModelMap#addAttribute(String, Object) * @see #getModelMap() */
public ModelAndView addObject(String attributeName, Object attributeValue) {  getModelMap().addAttribute(attributeName, attributeValue);  return this;
}  /** * Add an attribute to the model using parameter name generation. * @param attributeValue the object to add to the model (never <code>null</code>) * @see ModelMap#addAttribute(Object) * @see #getModelMap() */
public ModelAndView addObject(Object attributeValue) {  getModelMap().addAttribute(attributeValue);  return this;
}  /** * Add all attributes contained in the provided Map to the model. * @param modelMap a Map of attributeName -> attributeValue pairs * @see ModelMap#addAllAttributes(Map) * @see #getModelMap() */
public ModelAndView addAllObjects(Map<String, ?> modelMap) {  getModelMap().addAllAttributes(modelMap);  return this;
}  /** * Clear the state of this ModelAndView object. * The object will be empty afterwards. * <p>Can be used to suppress rendering of a given ModelAndView object * in the <code>postHandle</code> method of a HandlerInterceptor. * @see #isEmpty() * @see HandlerInterceptor#postHandle */
public void clear() {  this.view = null;  this.model = null;  this.cleared = true;
}  /** * Return whether this ModelAndView object is empty, * i.e. whether it does not hold any view and does not contain a model. */
public boolean isEmpty() {  return (this.view == null && CollectionUtils.isEmpty(this.model));
}  /** * Return whether this ModelAndView object is empty as a result of a call to {@link #clear} * i.e. whether it does not hold any view and does not contain a model. * <p>Returns <code>false</code> if any additional state was added to the instance * <strong>after</strong> the call to {@link #clear}. * @see #clear() */
public boolean wasCleared() {  return (this.cleared && isEmpty());
}  /** * Return diagnostic information about this model and view. */
@Override
public String toString() {  StringBuilder sb = new StringBuilder("ModelAndView: ");  if (isReference()) {  sb.append("reference to view with name '").append(this.view).append("'");  }  else {  sb.append("materialized View is [").append(this.view).append(']');  }  sb.append("; model is ").append(this.model);  return sb.toString();
} 

a 它有很多构造方法,对应会有很多使用方法:
例子:
(1)当你只有一个模型属性要返回时,可以在构造器中指定该属性来构造ModelAndView对象:

package com.apress.springrecipes.court.web;
...
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
public class WelcomeController extends AbstractController{  public ModelAndView handleRequestInternal(HttpServletRequest request,  HttpServletResponse response)throws Exception{  Date today = new Date();  return new ModelAndView("welcome","today",today);  }
} 

(2)如果有不止一个属性要返回,可以先将它们传递到一个Map中再来构造ModelAndView对象。

package com.apress.springrecipes.court.web;
...
import org.springframework.web.servlet.ModelAndView;
import org. springframework.web.servlet.mvc.AbstractController;
public class ReservationQueryController extends AbstractController{  ...  public ModelAndView handleRequestInternal(HttpServletRequest request,  HttpServletResponse response)throws Exception{  ...  Map<String,Object> model = new HashMap<String,Object>();  if(courtName != null){  model.put("courtName",courtName);  model.put("reservations",reservationService.query(courtName));  }  return new ModelAndView("reservationQuery",model);  }
}  

当然也可以使用spring提供的Model或者ModelMap,这是java.util.Map实现;

package com.apress.springrecipes.court.web;
...
import org.springframework.ui.ModelMap;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
public class ReservationQueryController extends AbstractController{  ...  public ModelAndView handleRequestInternal(HttpServletRequest request,  HttpServletResponse response)throws Exception{  ...  ModelMap model = new ModelMap();  if(courtName != null){  model.addAttribute("courtName",courtName);  model.addAttribute("reservations",reservationService.query(courtName));  }  return new ModelAndView("reservationQuery",model);  }
}  

在页面上可以通过el变量方式${key}或者bboss的一系列数据展示标签获取并展示modelmap中的数据;上面主要讲了ModelAndView的使用,其实Model与ModelMap使用方法都是一致;

下面我通过一个下例子展示一下:
在spring项目中,在配置文件中配置好 视图解析器:

<!-- 视图解析器 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!-- 前缀 --><property name="prefix" value="/WEB-INF/jsp/"/><!-- 后缀 --><property name="suffix" value=".jsp"/></bean>

在后台写:

    @RequestMapping("/test1")public ModelAndView test1(ModelMap mm ,HttpServletRequest request){ModelAndView mv = new ModelAndView("mytest");mv.addObject("key1","123");mm.addAttribute("key1","1234");return mv;}//前端为 123 123@RequestMapping("/test2")public String test2(ModelMap mm ,HttpServletRequest request){mm.addAttribute("key1", "1234");return "mytest";}//前端为 1234 1234 @RequestMapping("/test3")public String test3(Model mm ,HttpServletRequest request){mm.addAttribute("key1", "12345");return "mytest";}@RequestMapping("/test4")public String test4(Model mm ,HttpServletRequest request){mm.addAttribute("key1", "12345");request.setAttribute("key1", "123456");return "mytest";}//前端为 12345 12345@RequestMapping("/test5")public String test5(Model mm ,ModelMap mmp,HttpServletRequest request){request.setAttribute("key1", "123456");mm.addAttribute("key1", "12345");mmp.addAttribute("key1", "1234567");return "mytest";}//前端为 1234567 1234567

对应前端:

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title><%String test = String.valueOf(request.getAttribute("key1"));%>
</head>
<body>
<%=test %>${key1 }</body>
</html>

从上面测试可以看到Model,ModelMap与ModelAndView的具体使用;同时可以看出Model与ModelMap的值是能够替换的;并且两者赋值后作用比request.setAttribute()要大;这点在使用时需要注意;具体为啥,估计是最终解析时还是放在request上,最终还是替换了;我们知道

        request.setAttribute("key1", "123456");request.setAttribute("key1", "123457");

这样的代码最终得到的是“123457”;具体原因这里不看了,先学会熟练使用;

终上所述,我们知道了Model与ModelMap其实都是实现了hashMap,并且用法都是一样的;两者都是spring在请求时自动生成,拿来用便可;ModelAndView就是在两者的基础上可以指定返回页面;
赋值能力 ModelAndView > Model/ModelMap>request ;

附加: 转发与重定向:
a 原始servlet:

转发时可以将页面的资源传给另一个页面,使用相对路径!重定向只是单纯的进行页面跳转。使用绝对路径if(username.equals("123")&&password.equals("123")){  request.getRequestDispatcher("/success.html").forward(request, response);  }else{  //在sendRedict中url前必须加上当前web程序的路径名.....  response.sendRedirect(request.getContextPath()+"/fail.html");  }  

springMVC中,默认转发,重定向的话使用如下:

@RequestMapping("filesUpload")public String filesUpload(@RequestParam("files") MultipartFile[] files) {//判断file数组不能为空并且长度大于0if(files!=null&&files.length>0){//循环获取file数组中得文件for(int i = 0;i<files.length;i++){MultipartFile file = files[i];//保存文件saveFile(file);}}// 重定向return "redirect:/list.html";}

Spring中Model、ModelMap、ModelAndView理解和具体使用总结相关推荐

  1. Spring中Model,ModelMap以及ModelAndView之间的区别

    1.场景分析 在许多实际项目需求中,后台要从控制层直接返回前端所需的数据,这时Model大家族就派上用场了. 2.三者区别 ①Model Model是一个接口,它的实现类为ExtendedModelM ...

  2. Spring中Model、ModelMap及ModelAndView之间的区别

    1. Model(org.springframework.ui.Model) Model是一个接口,包含addAttribute方法,其实现类是ExtendedModelMap. ExtendedMo ...

  3. spring学习之springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序...

    spring mvc处理方法支持如下的返回方式:ModelAndView, Model, ModelMap, Map,View, String, void.下面将对具体的一一进行说明:ModelAnd ...

  4. 前端接modelmap的list_SpringMVC - 数据怎么从后端到前端?Model, ModelMap, ModelAndView

    总结 SpringMVC在调用方法前会创建一个隐含的数据模型(Model,ModelMap),作为模型数据的存储容器, 成为"隐含模型". 如果controller方法的参数为Mo ...

  5. springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序

    spring mvc处理方法支持如下的返回方式:ModelAndView, Model, ModelMap, Map,View, String, void.下面将对具体的一一进行说明: ModelAn ...

  6. Spring中对于WebApplicationInitializer的理解

    文章目录 1.前言 2.WebApplicationInitializer的定义 3.实现原理 4.利用SPI我们能做什么? 4.1.定义一个`MyWebAppInitializer` 4.2.定义一 ...

  7. spring 中单利模式的理解

    一.Spring单例模式与线程安全 Spring框架里的bean,或者说组件,获取实例的时候都是默认的单例模式,这是在多线程开发的时候要尤其注意的地方. 单例模式的意思就是只有一个实例.单例模式确保某 ...

  8. JSP隐含变量和Spring中Model在EL表达式中的读取顺序

    偶然中存在着必然,必然中存在着偶然 偶然出现的bug,必然存是由代码的不合理甚至错误的 代码逻辑越长,越复杂,就越容易出现bug 之前项目里几次偶然出现了一个bug,简单的描述就是第一次新增了之后进行 ...

  9. spring扩展点之二:spring中关于bean初始化、销毁等使用汇总,ApplicationContextAware将ApplicationContext注入...

    <spring扩展点之二:spring中关于bean初始化.销毁等使用汇总,ApplicationContextAware将ApplicationContext注入> <spring ...

最新文章

  1. java 获取内存使用情况_Java内存使用情况查看工具
  2. css实现一侧开口三角形
  3. Hadoop,Yarn,Zookeeper,kafka数据仓库集群命令集合
  4. 在doc中生成柱状图_Python从CSV文件导入数据和生成简单图表
  5. c语言 sizeof_c语言详解sizeof
  6. 导入工程后编译不过,报错: apply plugin: 'com.github.dcendents.android-maven'
  7. java内存加载dll_jacob调用dll控件,是否要执行内存释放,具体方法怎么写
  8. 案例-简介小米侧边栏(HTML、CSS)
  9. 机器学习实战Ch02: k-近邻算法
  10. 哈夫曼编码(自底向上的哈夫曼编码)
  11. cmake和make区别
  12. DarkAngels勒索病毒分析
  13. 倾斜摄影——3维建模软件PhotoScan教程(附安装包+教学视频)
  14. 各种分类算法的优缺点
  15. sap 新增科目表_在SAP中新建会计科目
  16. 【卸载双系统中的linux系统】删除引导
  17. 翻译狗文档免费下载手册(补充版)
  18. 头歌-自己动手画CPU(第一关)-8位可控加减法器-Logisim
  19. 云脉文档管理小程序使办公更协同
  20. 7种常用函数图象及4种函数图象变换规则

热门文章

  1. 用DirectX绘制使用纹理的立方体
  2. ES隔断时间会莫名其妙删除索引…………我头上一堆小朋友**喵喵机器人??还是病毒??
  3. css隐藏滚动条兼容IE,火狐,chrom
  4. mysql事物sql语句死锁,定时任务启动失败Lock wait timeout exceeded;try restarting transaction
  5. STM32工程添加模块、代码移植操作步骤
  6. 区块链游戏为何如此火?大概是因为投机者和“韭菜”太多
  7. 【WCN685X】WCN6856 5G吞吐量测试只有25Mbps问题原因分析及解决方案
  8. 征信报告产生“不良记录”的主要原因?
  9. Cascade-RCNN
  10. spicy之evt接口定义文件