摘要: spring MVC这个环境中,Spring MVC会依据controller(或者你叫它handler)中处理方法的返回值,进行解析,解析之后提供一个视图,作为响应。 标注了@Controller的处理器,实际上本质是一个POJO,你标注了@Controller,我就高看你一眼。

spring MVC这个环境中,Spring MVC会依据controller(或者你叫它handler)中处理方法的返回值,进行解析,解析之后提供一个视图,作为响应。
标注了@Controller的处理器,实际上本质是一个POJO,你标注了@Controller,我就高看你一眼。但你的形态就是一个java代码文件。
你作为一个java的土土的文件,你里面处理方法的返回值,也就是return语句,返回了一个东西。这个东西可以是String 也可以是 ModelAndView对象。这就是标注了@Controller的方法的全部工作。

接下来,Spring容器(或者说Spring MVC容器)需要接着你抛来的返回值,不管你的返回值是String还是ModelAndView,我,作为一个容器,我全都封装成ModelAndView对象。然后,我,Spring容器的一部分,视图解析器,开始工作。

视图解析器的英文名字叫做 ViewResolver,这个东西首先是Spring定义得人一个接口,具体你的Spring容器中的视图解析器有怎样的功能,取决于你为你自己的Spring容器配置了哪种具体的Spring视图解析器的实现类。

看看之前我们看过的一个图:
这个是spring mvc 的jar中的默认配置

当然你的spring项目也可以在配置文件中覆盖上述配置(我并没有用别的视图解析器取代默认的InternalResourceViewResolver):

/**
* @return 登录验证
*/
@RequestMapping("/dologin")
public ModelAndView dologin(HttpServletRequest request, User user) { User us1 = uss.getUserByName(user.getSrName());
ModelAndView mav = new ModelAndView();
mav.setViewName("forward:/login.jsp");
if (us1 == null) {
mav.addObject("errorMsg", "用户名不存在");
} else if (!us1.getSrPwd().equals(user.getSrPwd())) {
mav.addObject("errorMsg", "用户密码不正确");
} else { } return mav;
}

@Controller中的方法返回值最终都是ModelAndView,我们需要搞清楚两件事:
1.ModelAndView是什么?
2.视图解析器究竟做了哪些工作,才能返回我们需要的视图?

我们应该先看看ModelAndView是怎么回事:
ModelAndView是Spring中标准的类,完全是Spring自己封装的对象。Spring API中如此描述这个对象:
public class ModelAndView extends java.lang.Object

Holder for both Model and View in the web MVC framework. Note that these are entirely distinct. This class merely holds both to make it possible for a controller to return both model and view in a single return value.

Represents a model and view returned by a handler, to be resolved by a DispatcherServlet. The view can take the form of a String view name which will need to be resolved by a ViewResolver object; alternatively a View object can be specified directly. The model is a Map, allowing the use of multiple objects keyed by name.

用人话解释一下ModelAndView是干什么用的,ModelAndView包含两部分:一个View和一个Model
View由setViewName()方法来决定,决定让ViewResolver去哪里找View文件,并找到是哪个jsp文件;
Model由addObject()方法来决定,它的本质是java的HashMap,键值对;
用人话来解释ModelAndView的功能就是,View负责渲染Model,让你找到代表View的jsp,用这个jsp去渲染Model中的数据。

看看Spring源码:
Spring官网提供的API

去这个路径找一下:

也就是说ModelAndView对象中的核心成员就是Object和ModelMap
其中ModelMap也是Spring自己定义的对象。

ModelMap的本质是Java的标准容器:LinkedHashMap
属性成员我们已经搞清楚了,下面是方法成员:
setViewName()方法和addObject()方法

   public void setViewName(@Nullable String viewName)
{
this.view = viewName;
} public ModelAndView addObject(String attributeName, Object attributeValue)
{
getModelMap().addAttribute(attributeName, attributeValue);
return this;
} public ModelAndView addObject(Object attributeValue)
{
getModelMap().addAttribute(attributeValue);
return this;
} public ModelMap getModelMap()
{
if (this.model == null) {
this.model = new ModelMap();
}
return this.model;
}

也就是说,ModelAndView对象没有什么神秘之处,解构一下核心就是Object\LinkedHashMap,完全是Java的标准容器(对象)。
也就是说,关键不在于ModelAndView对象,而在于“视图解析器”这个Spring容器的核心部件。

那么视图解析器怎样工作呢?
你明明知道你用的ViewResolver的实现类就是InternalResourceViewResolver,那么你应该仔细看看Spring API中这一部分的详细内容:
https://docs.spring.io/spring/docs/5.0.1.RELEASE/javadoc-api/

首先InternalResourceViewResolver extends(继承)了 UrlBasedViewResolver;
然后顺便说,把用于显示(view)的jsp文件放在WEB-INF文件夹下是一种安全的做法,这样不能通过url直接access这些jsp,只能通过Controller java类来访问它们。

于是我们继续去看UrlBasedViewResolver

我想这样一个Spring官方的API中的说明性文字已经足以解开所有疑惑:那就是ModelAndView对象的方法setViewName()中的参数,看上去像是一个普通字符串的参数,究竟应该采用哪种格式?应该怎么写?已经有了定论。

As a special feature, redirect URLs can be specified via the "redirect:" prefix. E.g.: "redirect:myAction.do" will trigger a redirect to the given URL, rather than resolution as standard view name. This is typically used for redirecting to a controller URL after finishing a form workflow.

Furthermore, forward URLs can be specified via the "forward:" prefix. E.g.: "forward:myAction.do" will trigger a forward to the given URL, rather than resolution as standard view name. This is typically used for controller URLs; it is not supposed to be used for JSP URLs - use logical view names there

SpringMVC中ModelAndView对象与“视图解析器”的更多相关文章

  1. SpringMVC系列(七)视图解析器和视图

    在springmvc.xml里面配置视图解析器 <!-- 配置视图解析器: 如何把 handler 方法返回值解析为实际的物理视图 --> <bean class="org ...

  2. SpringMVC源码阅读:视图解析器

    1.前言 SpringMVC是目前J2EE平台的主流Web框架,不熟悉的园友可以看SpringMVC源码阅读入门,它交代了SpringMVC的基础知识和源码阅读的技巧 本文将通过源码(基于Spring ...

  3. springMVC源码分析--ViewResolver视图解析器(一)

    SpringMVC用于处理视图最重要的两个接口是ViewResolver和View.ViewResolver的主要作用是把一个逻辑上的视图名称解析为一个真正的视图,SpringMVC中用于把View对 ...

  4. SSM-SpringMVC-11:SpringMVC中ParameterMethodNameResolver参数方法名称解析器

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 或许曾经的我们也见过一种方式http://localhost:8080/项目名/后台servlet?actio ...

  5. SSM-SpringMVC-10:SpringMVC中PropertiesMethodNameResolver属性方法名称解析器

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 上次的以继承MultiActionController可以实现一个处理器中多个处理方法,但是局限出来了,他们的 ...

  6. SpringBoot使用ModelAndView时配置视图解析器

    spring boot 使用视图modelandview 原文:https://www.cnblogs.com/liyafei/p/7955943.html 1:springboot使用视图解析器,添 ...

  7. SpringMVC视图解析器概述

    不论控制器返回一个String,ModelAndView,View都会转换为ModelAndView对象,由视图解析器解析视图,然后,进行页面的跳转. 控制器处理方法---->ModelAndV ...

  8. SpringMVC中的视图和视图解析器

    对于控制器的目标方法,无论其返回值是String.View.ModelMap或是ModelAndView,SpringMVC都会在内部将它们封装为一个ModelAndView对象进行返回.  Spri ...

  9. 7.SpringMVC 配置式开发-ModelAndView和视图解析器

    ModelAndView 1.Model(模型) 1.model的本质就是HashMap,向模型中添加数据,就是往HashMap中去添加数据 2.HashMap 是一个单向查找数组,单向链表数组 3. ...

随机推荐

  1. linux matlab2016 安装

    1. 下载Matlab 2016b 下载文件夹中包含三个文件:Matlab 2016b Linux64 Crack.rar,R2016b_glnxa64_dvd1.iso,R2016b_glnxa64 ...

  2. Kaggle Titanic补充篇

    1.关于年龄Age 除了利用平均数来填充,还可以利用正态分布得到一些随机数来填充,首先得到已知年龄的平均数mean和方差std,然后生成[ mean-std,  mean+std ]之间的随机数,然后 ...

  3. pytorch官网上两个例程

    caffe用起来太笨重了,最近转到pytorch,用起来实在不要太方便,上手也非常快,这里贴一下pytorch官网上的两个小例程,掌握一下它的用法: 例程一:利用nn  这个module构建网络,实现 ...

  4. Vulcan 基于Meteor的APollO框架 , grapesjs 用于可视化生成Html 页面

    Vulcan 基于Meteor的APollO框架 :http://vulcanjs.org/ grapesjs 用于可视化生成Html    http://grapesjs.com/

  5. springboot系列十三、springboot集成swaggerUI

    一.Swagger介绍 Swagger能成为最受欢迎的REST APIs文档生成工具之一,有以下几个原因: Swagger 可以生成一个具有互动性的API控制台,开发者可以用来快速学习和尝试API. ...

  6. windows系统上搭建redis集群哨兵及主从复制

    搭建master 修改redis配置redis.windows.conf: 修改监听端口:  port 26379 修改绑定IP: bind 127.0.0.1 添加redis日志:logfile & ...

  7. PYTHON-模块 sys os random shutil

    import sys # 环境变量# print(sys.path)# # 查看已经加载的模块# print(sys.modules)# # 获取终端调用时的参数# print(sys.argv)# ...

  8. SpringMVC(1):Web MVC简介

    原文出处: 张开涛 Web MVC简介 1.1.Web开发中的请求-响应模型: 在Web世界里,具体步骤如下: 1.  Web浏览器(如IE)发起请求,如访问 2.  Web服务器(如Tomcat)接 ...

  9. java多线程快速入门(十五)

    使用violate关键字解决了变量的可见性问题(volatile让多线程刷新falg的值) package com.cppdy; class MyThread11 extends Thread { / ...

  10. myEclipse开发内存溢出解决办法myEclipse调整jvm内存大小java.lang.OutOfMemoryError: PermGen space及其解决方法

    摘要: tomcat部署多个项目后,启动tomcat正常,访问项目时却会出现该错误在网上查了查又试了好几次,才解决,将解决方法记录下来,以方便以后查看或让遇到同样问题的朋友有个参考 PermGen s ...