鹰击长空,鱼翔浅底,万类霜天竞自由

RedirectAttribute的用法及原理


重定向和转发是Web应用中常用的两种请求方式,这两种方式有着本质的区别。SpringMVC对两者提供了很好的支持,这篇文章介绍的就是SpringMVC对重定向的支持。首先,介绍一下重定向和转发的区别。

一句话概括二者的区别:“转发是服务器行为,重定向是客户端行为”

重定向:重定向在浏览器一端可以看到明显的URL跳转,实际上就是重新请求了另一个URL。重定向过程中,Request域的属性都将丢失,因为HTTP协议是无状态的协议,并且这已经是第二次HTTP请求了。

转发:“一次请求,一次响应”,地址栏的URL不会改变。转发是在服务器端执行,所以转发只能在同一台服务器上进行。它的特点是,速度快,并且Request域的属性不会丢失掉。

由此可见,重定向最大的弊端是,会丢失Request域中的属性。因此,SpringMVC采用RedirectAttribute来解决了这一问题。下面介绍一下SpirngMVC中重定向的所有方式,这其中包括RedirectAttribute

SpringMVCInternalResourceViewResolver支持带“命令”的逻辑视图名,所谓的命令就是“redirect:xxx”和“forward:xxx”,意思就是重定向或者跳转到指定的逻辑视图。

以下所有写法都可以实现请求的重定向:

		@RequestMapping("/")
		public String function(Model model) {
			model.addAttribute("test", 123);
			return "redirect:/index";
		}
		@RequestMapping("/")
		public String function(RedirectAttribute attribute) {
			attribute.addAttribute("test", 123);
			return "redirect:/index";
		}
		@RequestMapping("/")
		public String function(RedirectAttribute attribute) {
			attribute.addFlashAttribute("test", 123);
			return "redirect:/index";
		}

    前两者和后者有着明显的区别:经过实验发现,前两种方式会将设置的Attribute全不加到URL的请求参数上去,而最后一种方式却不在URL中加任何参数。 原因是,最后一种写法将Attribute放到了Session中去,在重定向的请求完毕后立刻删掉Session中的Attribute

    值得注意的是,SpringMVCSession的处理是透明的,并不是简单的将上一次请求所设置的Attribute放到SessionRequest中,而是做了简单的封装。 但是,却可以从重定向的JSP页面中获取到这个值。原因是,SpringMVC将这些Attribute放到了Model中,Controller执行完毕后,将Model中所有Attribute设置到Request中。

不过,SpringMVC依然提供了工具类,来访问Request域中封装的Attribute。下面两段代码就是访问这些Attribute的两种方式,不过一般不采用第二种方式。

		@RequestMapping("/index")
		public String function(Model model) {
			System.out.println(model.getAttribute("test"));
			return "redirect:/index";
		}
		Map<String, Object> attribute = RequestContextUtils.getFlashMapManager(request);

版权声明

本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。 本站博文除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。