之前两篇博客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(三)的更多相关文章

  1. springMVC源码分析--拦截器HandlerExecutionChain(三)

    上一篇博客springMVC源码分析--HandlerInterceptor拦截器调用过程(二)中我们介绍了HandlerInterceptor的执行调用地方,最终HandlerInterceptor ...

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

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

  3. springMVC源码分析--HandlerMapping(一)

    HandlerMapping的工作就是为每个请求找到合适的请求找到一个处理器handler,其实现机制简单来说就是维持了一个url到Controller关系的Map结构,其提供的实际功能也是根据req ...

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

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

  5. springMVC源码分析--ViewNameMethodReturnValueHandler返回值处理器(三)

    之前两篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)和springMVC源码分析--HandlerMethodReturnValu ...

  6. springMVC源码分析--视图AbstractView和InternalResourceView(二)

    上一篇博客springMVC源码分析--视图View(一)中我们介绍了简单介绍了View的结构实现及运行流程,接下来我们介绍一下View的实现类做的处理操作. AbstractView实现了rende ...

  7. SpringMVC源码分析6:SpringMVC的视图解析原理

    title: SpringMVC源码分析6:SpringMVC的视图解析原理 date: 2018-06-07 11:03:19 tags: - SpringMVC categories: - 后端 ...

  8. [心得体会]SpringMVC源码分析

    1. SpringMVC (1) springmvc 是什么? 前端控制器, 主要控制前端请求分配请求任务到service层获取数据后反馈到springmvc的view层进行包装返回给tomcat, ...

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

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

随机推荐

  1. H5新特性之geolocation

    geolocation是H5新增的对象,它用于定位,继承在navigator对象内,以前用navigator只用到userAgent,现在就多了这个geolocation 有2种方法(getCurre ...

  2. shell if [[ ]]的一次应用

    直接上代码 #!/bin/bash A="$1" if [[ "$A" == a* ]];then echo "aaa" else echo ...

  3. Linux系统加固

    iptables 初始化 > iptables -F #清空所有的链 > iptables -X #清空所有自定义的链 关掉全部端口 > iptables -P INPUT DROP ...

  4. 关于js事件执行顺序小技巧

    js事件执行顺序是js中一个老生常谈的一个话题, 聊这个话题之前我们先谈谈怎么给页面元素绑定我们需要的事件 1.给页面元素绑定事件 a)直接在元素上面加上需要绑定的事件,如 <button ty ...

  5. HDU - 4901 The Romantic Hero(dp)

    https://vjudge.net/problem/HDU-4901 题意 给n个数,构造两个集合,使第一个集合的异或和等于第二个集合的相与和,且要求第一个集合的元素下标都小于第二个集合的元素下标. ...

  6. JAVA实现具有迭代器的线性表(顺序表)

    1,先了解下JAVA类库中的迭代器:JAVA提供了两种基本类型的迭代器,分别用两个接口来表示:Iterator<T>,ListIterator<T>.其中,Iterator&l ...

  7. CSS——超链接颜色设置

    <!-- 链接颜色 --> a:link { color:#FF0000; text-decoration:underline; } a:visited { color:#00FF00; ...

  8. 第2章 线性表《C#数据结构和算法》

    ( )除第一个位置的数据 元素外,其它数据元素位置的前面都只有一个数据元素:( )除最后一个位置的 数据元素外,其它数据元素位置的后面都只有一个元素.也就是说,数据元素是 一个接一个的排列.因此,可以 ...

  9. Django学习手册 - 自定义simple_tag / filter

    相关: Django的模板引擎提供一般性的功能函数,通过前端可以实现多数的代码逻辑功能,但它仅支持大多数常见情况下的函数功能,例如if判断,ifequal对比返回值等,复杂一些的函数功能并不支持,例如 ...

  10. VS2013+Win10+opencv3.0配置(包括opencv2.4.10版本)

    在win下配置opencv3.0.0还是比较简单的,这里简单说一下配置过程:参考链接:http://blog.csdn.net/u010009145/article/details/50756751 ...