ModelAndViewContainer、ModelMap、Model、ModelAndView详细介绍【享学Spring MVC】(下)

简介: ModelAndViewContainer、ModelMap、Model、ModelAndView详细介绍【享学Spring MVC】(下)

BindingAwareModelMap


注意:它和普通ModelMap的区别是:它能感知数据校验结果(如果放进来的key存在对应的绑定结果,并且你的value不是绑定结果本身。那就移除掉MODEL_KEY_PREFIX + key这个key的键值对~)


public class BindingAwareModelMap extends ExtendedModelMap {
  // 注解复写了Map的put方法,一下子就拦截了所有的addAttr方法。。。
  @Override
  public Object put(String key, Object value) {
    removeBindingResultIfNecessary(key, value);
    return super.put(key, value);
  }
  @Override
  public void putAll(Map<? extends String, ?> map) {
    map.forEach(this::removeBindingResultIfNecessary);
    super.putAll(map);
  }
  // 本类处理的逻辑:
  private void removeBindingResultIfNecessary(Object key, Object value) {
    // key必须是String类型才会给与处理
    if (key instanceof String) {
      String attributeName = (String) key;
      if (!attributeName.startsWith(BindingResult.MODEL_KEY_PREFIX)) {
        String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + attributeName;
        BindingResult bindingResult = (BindingResult) get(bindingResultKey);
        // 如果有校验结果,并且放进来的value值不是绑定结果本身,那就移除掉绑定结果(相当于覆盖掉)
        if (bindingResult != null && bindingResult.getTarget() != value) {
          remove(bindingResultKey);
        }
      }
    }
  }
}


Spring MVC默认使用的就是这个ModelMap,但它提供的感知功能大多数情况下我们都用不着。不过反正也不用你管,乖乖用着呗


ModelAndView

顾名思义,ModelAndView指模型和视图的集合,既包含模型又包含视图;ModelAndView一般可以作为Controller的返回值,所以它的实例是开发者自己手动创建的,这也是它和上面的主要区别(上面都是容器创建,然后注入给我们使用的~)

因为这个类是直接面向开发者的,所以建议里面的一些API还是要熟悉点较好:

public class ModelAndView {
  @Nullable
  private Object view; // 可以是View,也可以是String
  @Nullable
  private ModelMap model;
  // 显然,你也可以自己就放置好一个http状态码进去
  @Nullable
  private HttpStatus status;  
  // 标记这个实例是否被调用过clear()方法~~~
  private boolean cleared = false;
  // 总共这几个属性:它提供的构造函数非常的多  这里我就不一一列出
  public void setViewName(@Nullable String viewName) {
    this.view = viewName;
  }
  public void setView(@Nullable View view) {
    this.view = view;
  }
  @Nullable
  public String getViewName() {
    return (this.view instanceof String ? (String) this.view : null);
  }
  @Nullable
  public View getView() {
    return (this.view instanceof View ? (View) this.view : null);
  }
  public boolean hasView() {
    return (this.view != null);
  }
  public boolean isReference() {
    return (this.view instanceof String);
  }
  // protected方法~~~
  @Nullable
  protected Map<String, Object> getModelInternal() {
    return this.model;
  }
  public ModelMap getModelMap() {
    if (this.model == null) {
      this.model = new ModelMap();
    }
    return this.model;
  }
  // 操作ModelMap的一些方法如下:
  // addObject/addAllObjects
  public void clear() {
    this.view = null;
    this.model = null;
    this.cleared = true;
  }
  // 前提是:this.view == null 
  public boolean isEmpty() {
    return (this.view == null && CollectionUtils.isEmpty(this.model));
  }
  // 竟然用的was,歪果仁果然严谨  哈哈
  public boolean wasCleared() {
    return (this.cleared && isEmpty());
  }
}


很多人疑问:为何Controller的处理方法不仅仅可以返回ModelAndView,还可以通过返回Map/Model/ModelMap等来直接向页面传值呢???如果返回值是后三者,又是如何找到view完成渲染的呢?


这个问题我抛出来,本文不给答案。因为都聊到这了,此问题应该不算难的了,建议小伙伴必须自行弄懂缘由(请不要放过有用的知识点)。若实在有不懂之处可以给留言我会帮你解答的~

答案参考提示:可参阅ModelMethodProcessor和ModelMethodProcessor对返回值的处理模块


绝大多数情况下,我都建议返回ModelAndView,而不是其它那哥三。因为它哥三都没有指定视图名,所以通过DispatcherServlet.applyDefaultViewName()生成的视图名一般都不是我们需要的。(除非你的目录、命名等等都特别特别的规范,那顺便倒是可以省不少事~~~)


ModelFactory


关于ModelFactory它的介绍,这篇文章 里算是已经详细讲解过了,这里再简述两句它的作用。

ModelFactory是用来维护Model的,具体包含两个功能


  1. 初始化Model
  2. 处理器执行后将Model中相应的参数更新到SessionAttributes中(处理@ModelAttribute和@SessionAttributes)


总结


本以为本文不会很长的,没想到还是写成了超10000字的中篇文章。希望这篇文章能够帮助你对Spring MVC对模型、视图这块核心内容的理解,帮你扫除途中的一些障碍,共勉~

相关文章
|
1月前
|
JSON 前端开发 Java
SSM:SpringMVC
本文介绍了SpringMVC的依赖配置、请求参数处理、注解开发、JSON处理、拦截器、文件上传下载以及相关注意事项。首先,需要在`pom.xml`中添加必要的依赖,包括Servlet、JSTL、Spring Web MVC等。接着,在`web.xml`中配置DispatcherServlet,并设置Spring MVC的相关配置,如组件扫描、默认Servlet处理器等。然后,通过`@RequestMapping`等注解处理请求参数,使用`@ResponseBody`返回JSON数据。此外,还介绍了如何创建和配置拦截器、文件上传下载的功能,并强调了JSP文件的放置位置,避免404错误。
|
1月前
|
前端开发 Java 应用服务中间件
【Spring】Spring MVC的项目准备和连接建立
【Spring】Spring MVC的项目准备和连接建立
57 2
|
2月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
1月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
123 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
|
2月前
|
XML 缓存 前端开发
springMVC02,restful风格,请求转发和重定向
文章介绍了RESTful风格的基本概念和特点,并展示了如何使用SpringMVC实现RESTful风格的请求处理。同时,文章还讨论了SpringMVC中的请求转发和重定向的实现方式,并通过具体代码示例进行了说明。
springMVC02,restful风格,请求转发和重定向
|
3月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
3月前
|
XML JSON 数据库
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
这篇文章详细介绍了RESTful的概念、实现方式,以及如何在SpringMVC中使用HiddenHttpMethodFilter来处理PUT和DELETE请求,并通过具体代码案例分析了RESTful的使用。
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
|
3月前
|
前端开发 应用服务中间件 数据库
SpringMVC入门到实战------八、RESTful案例。SpringMVC+thymeleaf+BootStrap+RestFul实现员工信息的增删改查
这篇文章通过一个具体的项目案例,详细讲解了如何使用SpringMVC、Thymeleaf、Bootstrap以及RESTful风格接口来实现员工信息的增删改查功能。文章提供了项目结构、配置文件、控制器、数据访问对象、实体类和前端页面的完整源码,并展示了实现效果的截图。项目的目的是锻炼使用RESTful风格的接口开发,虽然数据是假数据并未连接数据库,但提供了一个很好的实践机会。文章最后强调了这一章节主要是为了练习RESTful,其他方面暂不考虑。
SpringMVC入门到实战------八、RESTful案例。SpringMVC+thymeleaf+BootStrap+RestFul实现员工信息的增删改查
|
3月前
|
前端开发 JavaScript
MVC中简单数据模型(M): Model类
MVC中简单数据模型(M): Model类
|
3月前
|
JSON 前端开发 Java
Spring MVC返回JSON数据
综上所述,Spring MVC提供了灵活、强大的方式来支持返回JSON数据,从直接使用 `@ResponseBody`及 `@RestController`注解,到通过配置消息转换器和异常处理器,开发人员可以根据具体需求选择合适的实现方式。
167 4
下一篇
无影云桌面