看一段普通的代码,我们访问controller中的一个方法后,重定向到另外一个controller或者视图。

    @RequestMapping(params="method=index")
public ModelAndView index() {
RedirectView redirectView = new RedirectView("/Demo.do?method=index2", true, true);
ModelAndView mav = new ModelAndView(redirectView);
mav.addObject("attr1", "attr1Value");
mav.addObject("attr2", "attr2Value");
return mav;
}

浏览器的URL会变成http://localhost:8080/FuDeKang/Demo.do?method=index2&attr2=attr2Value&attr1=attr1Value

也就是说Spring会自定把model中的键值放入到URL当中,那么Spring是如何做到的呢,我么还来看ModelAndViewMethodReturnValueHandler这个类。

public class ModelAndViewMethodReturnValueHandler implements HandlerMethodReturnValueHandler {

    public boolean supportsReturnType(MethodParameter returnType) {
return ModelAndView.class.isAssignableFrom(returnType.getParameterType());
} public void handleReturnValue(
Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
throws Exception { if (returnValue == null) {
mavContainer.setRequestHandled(true);
return;
} ModelAndView mav = (ModelAndView) returnValue;
if (mav.isReference()) {
String viewName = mav.getViewName();
mavContainer.setViewName(viewName);
if (viewName != null && viewName.startsWith("redirect:")) {
mavContainer.setRedirectModelScenario(true);
}
}
else {
View view = mav.getView();
mavContainer.setView(view);
if (view instanceof SmartView) {
if (((SmartView) view).isRedirectView()) {
mavContainer.setRedirectModelScenario(true);
}
}
}
mavContainer.addAllAttributes(mav.getModel());
} }

其中最后一句是关键,首先modelandview当中的model数据全部放到ModelAndViewContainer 里面。

因为我们是重定向,所以无论如何底层最后产生的视图对象都是RedirectView实例,我们在看一下它的源码。

    /**
* Convert model to request parameters and redirect to the given URL.
* @see #appendQueryProperties
* @see #sendRedirect
*/
@Override
protected void renderMergedOutputModel(
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response)
throws IOException { String targetUrl = createTargetUrl(model, request); targetUrl = updateTargetUrl(targetUrl, model, request, response); FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request);
if (!CollectionUtils.isEmpty(flashMap)) {
UriComponents uriComponents = UriComponentsBuilder.fromUriString(targetUrl).build();
flashMap.setTargetRequestPath(uriComponents.getPath());
flashMap.addTargetRequestParams(uriComponents.getQueryParams());
} FlashMapManager flashMapManager = RequestContextUtils.getFlashMapManager(request);
flashMapManager.saveOutputFlashMap(flashMap, request, response); sendRedirect(request, response, targetUrl.toString(), this.http10Compatible);
}

其中  targetUrl = updateTargetUrl(targetUrl, model, request, response);  是拼接了URL的代码,最后调用sendRedirect做重定向。

SpringMVC RedirectView的使用以及源码分析的更多相关文章

  1. 面试高频SpringMVC执行流程最优解(源码分析)

    文章已托管到GitHub,大家可以去GitHub查看阅读,欢迎老板们前来Star! 搜索关注微信公众号 码出Offer 领取各种学习资料! SpringMVC执行流程 SpringMVC概述 Spri ...

  2. SpringMVC执行流程及源码分析

    SpringMVC流程及源码分析 前言 ​ 学了一遍SpringMVC以后,想着做一个总结,复习一下.复习写下面的总结的时候才发现,其实自己学的并不彻底.牢固.也没有学全,视频跟书本是要结合起来一起, ...

  3. springMVC源码分析--页面跳转RedirectView(三)

    之前两篇博客springMVC源码分析--视图View(一)和springMVC源码分析--视图AbstractView和InternalResourceView(二)中我们已经简单的介绍了View相 ...

  4. SpringMVC源码分析系列

    说到java的mvc框架,struts2和springmvc想必大家都知道,struts2的设计基本上完全脱离了Servlet容器,而springmvc是依托着Servlet容器元素来设计的,同时sp ...

  5. SpringMVC视图机制详解[附带源码分析]

    目录 前言 重要接口和类介绍 源码分析 编码自定义的ViewResolver 总结 参考资料 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门bl ...

  6. 8、SpringMVC源码分析(3):分析ModelAndView的形成过程

    首先,我们还是从DispatcherServlet.doDispatch(HttpServletRequest request, HttpServletResponse response) throw ...

  7. 深入源码分析SpringMVC底层原理(二)

    原文链接:深入源码分析SpringMVC底层原理(二) 文章目录 深入分析SpringMVC请求处理过程 1. DispatcherServlet处理请求 1.1 寻找Handler 1.2 没有找到 ...

  8. springMVC源码分析--FlashMap和FlashMapManager重定向数据保存

    在上一篇博客springMVC源码分析--页面跳转RedirectView(三)中我们看到了在RedirectView跳转时会将跳转之前的请求中的参数保存到fFlashMap中,然后通过FlashMa ...

  9. springMVC源码分析--视图View(一)

    之前的博客springMVC源码分析--HttpMessageConverter数据转化(一)中我们已经介绍了数据返回值的处理,在博客springMVC源码分析--ViewResolver视图解析器( ...

随机推荐

  1. Nginx启动/重启脚本详解

    Nginx手动启动 停止操作 停止操作是通过向nginx进程发送信号(什么是信号请参阅linux文 章)来进行的步骤1:查询nginx主进程号ps -ef | grep nginx在进程列表里 面找m ...

  2. Python 文件 write() 方法

    概述 Python 文件 write() 方法用于向文件中写入指定字符串. 在文件关闭前或缓冲区刷新前,字符串内容存储在缓冲区中,这时你在文件中是看不到写入的内容的. 语法 write() 方法语法如 ...

  3. nginx Server names

    通配符名称 正則表達式名称 混合名称 优化 兼容性 server名称定义使用的server_name指令和决定哪个server块用于一个给定的请求. 參见"怎样Nginx处理一个请求&quo ...

  4. 针对MSHFlexGrid的一系列通用方法-项目中实践代码分享

    1.给MSHFlexGrid填充数据通用方法 '自定义报表填充程序 fgrid Public Function ShowformfData(Resultset As ADODB.Recordset, ...

  5. 使用mysqltools配置读写分离环境

    mysqltools 目前自带了cat的的自动化安装功能 一.环境规划: 主机名 ip地址 角色 mtls17 10.186.19.17 master mtls19 10.186.19.19 slav ...

  6. 使用maven-shade-plugin插件解决spark依赖冲突问题

    依赖冲突:NoSuchMethodError,ClassNotFoundException   当用户应用于Spark本身依赖同一个库时可能会发生依赖冲突,导致程序奔溃.依赖冲突表现为在运行中出现No ...

  7. vim的Tab键

    vim中默认的tab键大约是6个空格(目测)的宽度.如果想修改为4个空格,用以下命令:    shiftwidth=4    softtabstop-4shiftwidth的含义是:回车后需要缩进时, ...

  8. 批处理向FTP上传指定属性的文件 批处理增量备份的例子

    使用windows批处理向FTP上传具有指定属性的文件,类似增量备份功能. 对一个目录里的几个文件自动上传FTP时只上传有归档属性的文件,然后FTP上传成功后自动清除(本机)刚上传文件的归档属性. 类 ...

  9. Java常考面试题(二)

    序言 昨天刚开始的”每日5题面试“这类文章,感觉还不错,把一些平常看似懂了的东西,弄清楚了.就像什么是虚拟机?这个问题,看起来知道,但是要说出个所以然来,又懵逼了,经常回过头来看看做过的面试题,试着用 ...

  10. 菜鸟学SSH(十)——Hibernate核心接口

    在使用Hibernate的时候,我们通常都会用的Configuration.SessionFactory.Session.Transaction.Query和Criteria等接口.通过这些接口可以, ...