SpringMVC中ModelAndView对象与“视图解析器”

简介: 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中的默认配置
screenshot
当然你的spring项目也可以在配置文件中覆盖上述配置(我并没有用别的视图解析器取代默认的InternalResourceViewResolver):
screenshot

/**
     * @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
screenshot
去这个路径找一下:
screenshot
也就是说ModelAndView对象中的核心成员就是Object和ModelMap
其中ModelMap也是Spring自己定义的对象。
screenshot
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对象没有什么神秘之处,解构一下核心就是ObjectLinkedHashMap,完全是Java的标准容器(对象)。
也就是说,关键不在于ModelAndView对象,而在于“视图解析器”这个Spring容器的核心部件。

那么视图解析器怎样工作呢?
你明明知道你用的ViewResolver的实现类就是InternalResourceViewResolver,那么你应该仔细看看Spring API中这一部分的详细内容:
https://docs.spring.io/spring/docs/5.0.1.RELEASE/javadoc-api/
screenshot
首先InternalResourceViewResolver extends(继承)了 UrlBasedViewResolver;
然后顺便说,把用于显示(view)的jsp文件放在WEB-INF文件夹下是一种安全的做法,这样不能通过url直接access这些jsp,只能通过Controller java类来访问它们。

于是我们继续去看UrlBasedViewResolver
screenshot
我想这样一个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.

上述两段文字就是forward和redirect两个关键词的用法。

受到这篇文章的启发:http://blog.sina.com.cn/s/blog_6d3c1ec601014h1h.html

目录
相关文章
|
26天前
|
负载均衡 算法 Java
Spring Cloud全解析:负载均衡算法
本文介绍了负载均衡的两种方式:集中式负载均衡和进程内负载均衡,以及常见的负载均衡算法,包括轮询、随机、源地址哈希、加权轮询、加权随机和最小连接数等方法,帮助读者更好地理解和应用负载均衡技术。
|
10天前
|
Java 对象存储 开发者
解析Spring Cloud与Netflix OSS:微服务架构中的左右手如何协同作战
Spring Cloud与Netflix OSS不仅是现代微服务架构中不可或缺的一部分,它们还通过不断的技术创新和社区贡献推动了整个行业的发展。无论是对于初创企业还是大型组织来说,掌握并合理运用这两套工具,都能极大地提升软件系统的灵活性、可扩展性以及整体性能。随着云计算和容器化技术的进一步普及,Spring Cloud与Netflix OSS将继续引领微服务技术的发展潮流。
25 0
|
3月前
|
设计模式 监控 Java
解析Spring Cloud中的断路器模式原理
解析Spring Cloud中的断路器模式原理
|
3月前
|
安全 Java 数据安全/隐私保护
解析Spring Security中的权限控制策略
解析Spring Security中的权限控制策略
|
24天前
|
XML 监控 Java
Spring Cloud全解析:熔断之Hystrix简介
Hystrix 是由 Netflix 开源的延迟和容错库,用于提高分布式系统的弹性。它通过断路器模式、资源隔离、服务降级及限流等机制防止服务雪崩。Hystrix 基于命令模式,通过 `HystrixCommand` 封装对外部依赖的调用逻辑。断路器能在依赖服务故障时快速返回备选响应,避免长时间等待。此外,Hystrix 还提供了监控功能,能够实时监控运行指标和配置变化。依赖管理方面,可通过 `@EnableHystrix` 启用 Hystrix 支持,并配置全局或局部的降级策略。结合 Feign 可实现客户端的服务降级。
101 23
|
8天前
|
存储 缓存 Java
在Spring Boot中使用缓存的技术解析
通过利用Spring Boot中的缓存支持,开发者可以轻松地实现高效和可扩展的缓存策略,进而提升应用的性能和用户体验。Spring Boot的声明式缓存抽象和对多种缓存技术的支持,使得集成和使用缓存变得前所未有的简单。无论是在开发新应用还是优化现有应用,合理地使用缓存都是提高性能的有效手段。
14 1
|
1月前
|
设计模式 存储 人工智能
深度解析Unity游戏开发:从零构建可扩展与可维护的游戏架构,让你的游戏项目在模块化设计、脚本对象运用及状态模式处理中焕发新生,实现高效迭代与团队协作的完美平衡之路
【9月更文挑战第1天】游戏开发中的架构设计是项目成功的关键。良好的架构能提升开发效率并确保项目的长期可维护性和可扩展性。在使用Unity引擎时,合理的架构尤为重要。本文探讨了如何在Unity中实现可扩展且易维护的游戏架构,包括模块化设计、使用脚本对象管理数据、应用设计模式(如状态模式)及采用MVC/MVVM架构模式。通过这些方法,可以显著提高开发效率和游戏质量。例如,模块化设计将游戏拆分为独立模块。
76 3
|
1月前
|
JavaScript 前端开发 API
Javaweb之javascript的BOM对象的详细解析
BOM为Web开发提供了强大的API,允许开发者与浏览器进行深入的交互。合理使用BOM中的对象和方法,可以极大地增强Web应用的功能性和用户体验。需要注意的是,BOM的某些特征可能会在不同浏览器中表现不一致,因此在开发过程中需要进行仔细的测试和兼容性处理。通过掌握BOM,开发者能够制作出更丰富、更动态、更交互性的JavaWeb应用。
17 1
|
2月前
|
缓存 Java 开发者
Spring高手之路22——AOP切面类的封装与解析
本篇文章深入解析了Spring AOP的工作机制,包括Advisor和TargetSource的构建与作用。通过详尽的源码分析和实际案例,帮助开发者全面理解AOP的核心技术,提升在实际项目中的应用能力。
23 0
Spring高手之路22——AOP切面类的封装与解析
|
2月前
|
Java 微服务 Spring
Spring Cloud全解析:配置中心之解决configserver单点问题
但是如果该configserver挂掉了,那就无法获取最新的配置了,微服务就出现了configserver的单点问题,那么如何避免configserver单点呢?

热门文章

最新文章

推荐镜像

更多
下一篇
无影云桌面