springMVC源码分析--页面跳转RedirectView(三)
之前两篇博客springMVC源码分析--视图View(一)和springMVC源码分析--视图AbstractView和InternalResourceView(二)中我们已经简单的介绍了View相关的知识,接下来我们介绍一个比较常用的RedirectView,顾名思义RedirectView是用于页面跳转使用的。
跳转的示例:
@RequestMapping("/index")
public String index(Model model,RedirectAttributes attr){
attr.addAttribute("attributeName", "attributeValue");
model.addAttribute("book", "金刚经");
model.addAttribute("description","不擦擦擦擦擦擦擦车"+new Random().nextInt(100));
model.addAttribute("price", new Double("1000.00"));
model.addAttribute("attributeName1", "attributeValue1");
//跳转之前将数据保存到book、description和price中,因为注解@SessionAttribute中有这几个参数
return "redirect:get.action";
}
返回的值为“redirect:get.action”,这样在处理之后我们会看到浏览器会跳转到get.action中,首先我们需要了解请求的跳转会在浏览器中修改请求链接,这样跳转的请求和原请求就是两个不相干的请求,跳转的请求会丢失掉原请求的中的所有数据,一般的解决方法是将原请求中的数据放到跳转请求的链接中这样来获取数据。接下来我们看看springMVC的RediectView所做的处理,让我们不用关心原请求中的值问题。
首先当返回值为"redirect:get.action"时,会调用ViewNameMethodReturnValueHandler的handleReturnValue方法,判断是否是跳转页面,设置跳转标记
ViewNameMethodReturnValueHandler中的实现如下:
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
if (returnValue instanceof CharSequence) {
String viewName = returnValue.toString();
mavContainer.setViewName(viewName);
//用于判断是否是跳转页面 redirect
if (isRedirectViewName(viewName)) {
mavContainer.setRedirectModelScenario(true);
}
}
else if (returnValue != null){
// should not happen
throw new UnsupportedOperationException("Unexpected return type: " +
returnType.getParameterType().getName() + " in method: " + returnType.getMethod());
}
}
当判断页面是跳转页面是ViewResolver生成的View对象是RedirectView,这样就可以实现页面跳转工作了。
接下来我们看看在RedirectView中所做的操作,最终的实现是在renderMergedOutputModel中完成实现的,这边需要实现的机制是在连接重定向时数据会丢失,这样使用FlashMap将数据保存起来作为重定向后的数据使用。
@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);
if (flashMapManager == null) {
throw new IllegalStateException("FlashMapManager not found despite output FlashMap having been set");
}
//将数据保存起来,作为跳转之后请求的数据使用
flashMapManager.saveOutputFlashMap(flashMap, request, response);
}
//重定向操作
sendRedirect(request, response, targetUrl, this.http10Compatible);
}
简单来说RedirectView实现了链接的重定向,并且将数据保存到FlashMap中,这样在跳转后的链接中可以获取一些数据。
springMVC源码分析--页面跳转RedirectView(三)的更多相关文章
- springMVC源码分析--拦截器HandlerExecutionChain(三)
上一篇博客springMVC源码分析--HandlerInterceptor拦截器调用过程(二)中我们介绍了HandlerInterceptor的执行调用地方,最终HandlerInterceptor ...
- springMVC源码分析--FlashMap和FlashMapManager重定向数据保存
在上一篇博客springMVC源码分析--页面跳转RedirectView(三)中我们看到了在RedirectView跳转时会将跳转之前的请求中的参数保存到fFlashMap中,然后通过FlashMa ...
- springMVC源码分析--HandlerMapping(一)
HandlerMapping的工作就是为每个请求找到合适的请求找到一个处理器handler,其实现机制简单来说就是维持了一个url到Controller关系的Map结构,其提供的实际功能也是根据req ...
- springMVC源码分析--视图View(一)
之前的博客springMVC源码分析--HttpMessageConverter数据转化(一)中我们已经介绍了数据返回值的处理,在博客springMVC源码分析--ViewResolver视图解析器( ...
- springMVC源码分析--ViewNameMethodReturnValueHandler返回值处理器(三)
之前两篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)和springMVC源码分析--HandlerMethodReturnValu ...
- springMVC源码分析--视图AbstractView和InternalResourceView(二)
上一篇博客springMVC源码分析--视图View(一)中我们介绍了简单介绍了View的结构实现及运行流程,接下来我们介绍一下View的实现类做的处理操作. AbstractView实现了rende ...
- SpringMVC源码分析6:SpringMVC的视图解析原理
title: SpringMVC源码分析6:SpringMVC的视图解析原理 date: 2018-06-07 11:03:19 tags: - SpringMVC categories: - 后端 ...
- [心得体会]SpringMVC源码分析
1. SpringMVC (1) springmvc 是什么? 前端控制器, 主要控制前端请求分配请求任务到service层获取数据后反馈到springmvc的view层进行包装返回给tomcat, ...
- 8、SpringMVC源码分析(3):分析ModelAndView的形成过程
首先,我们还是从DispatcherServlet.doDispatch(HttpServletRequest request, HttpServletResponse response) throw ...
随机推荐
- 基于URL的HAProxy负载均衡设置
例子包括ACL的url_beg. url_beg提交URL中使用的字符串相匹配. 使用URL /blog(cnblog/api)所有请求重定向到WEB服务器的6200端口.所有其他请求将重定向到服务器 ...
- 《springCloud系列》——Eureka 进行服务治理
整理一下: @EnableEurekaServer 注册中心 @EnableDiscoveryClient 提供服务 @EnableFeignClients 消费者(Feign特有的,而且他自带断路器 ...
- JS基础:翻转数组
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; console.log(arr); //操作原数组,让原数组第一位和最后一个位调换位置,以此类推. for (va ...
- 简述var、let、const三者的区别
前二者为定义变量,const一般用来定义常量. 1.var声明变量可以重复声明,而let不可以重复声明 var name = 'xiaohuang'; var name = 'xiaolan'; co ...
- 自动部署tomcat,并以普通用户身份运行 for centos6
#!/bin/bash ######## install jdk install_jdk () { rpm -e ‘rpm -qa |grep jdk’ wget \ --no-check-certi ...
- Linux安装mysql过程(转+完善)
http://blog.csdn.net/jerome_s/article/details/52883234yum 安装MySQL 1. 检查安装情况 查看有没有安装过: ...
- collocation
a collocation is two or more words that often go together. These combination just sound "right& ...
- 数据库之MySQL ERROR 1698 (28000) 错误:Access denied for user 'root'@'localhost'" error【摘抄】
声明:全文均摘抄于MySQL ERROR 1698 (28000) 错误 //错误起源: ~$ mysql -u root -p Enter password: ERROR 1698 (28000): ...
- Java SE之向上转型与向下转型
package object; //向上转型-向下转型 public class Up_Down_convert { /* 向上转型 * * 1.上转型对象可以使用和操作子类继承或者重写的方法 * 2 ...
- 最新Linux系统Ubuntu16.04搭建HUSTOJ(LAMP环境)
应该跟着下面的步骤就OK了吧! 1.升级软件库,更新软件 打开终端 输入 sudo apt-get update sudo apt-get upgrade 2.安装mysql5.7 (注意:mysql ...