Spring MVC RedirectAttributes的用法

执笔记忆的空白 XXX XXX  2015-05-12 06:35:22
加精
很久没发过技术贴了,今天对于一个问题纠结了2小时,遂放弃研究用另一种方法解决,奈何心中一直存在纠结,发帖求解

我先解释下什么是RedirectAttributes

RedirectAttributes是Spring mvc 3.1版本之后出来的一个功能,专门用于重定向之后还能带参数跳转的
他有两种带参的方式:
第一种:
attr.addAttribute("param", value);
这种方式就相当于重定向之后,在url后面拼接参数,这样在重定向之后的页面或者控制器再去获取url后面的参数就可以了,但这个方式因为是在url后面添加参数的方式,所以暴露了参数,有风险
例:

attr.addFlashAttribute("name", "123");
attr.addFlashAttribute("success", "success");
return "redirect:/index";

这样就相当于:return "redirect:/index?name=123&success=success"

第二种:
attr.addFlashAttribute("param", value);
这种方式也能达到重新向带参,而且能隐藏参数,其原理就是放到session中,session在跳到页面后马上移除对象。所以你刷新一下后这个值就会丢掉
例:

attr.addFlashAttribute("status","999");
attr.addFlashAttribute("message","登录失败");
return "redirect:/toLogin";

这种方式确实能重定向带参,但是有个问题,这个只能重定向到页面上,也就是说重定向的这个页面视图,能用el表达式直接获取你带参的值,比如status 和message ,都能获取。 可是我重定向到另一个Controller的时候,这个控制器里面没法获取这两个参数

我现在有个需求:登录成功,直接重定向其他页面,登录失败,又得重定向到登录页面,直接return的还不行,但是又要带状态码和提示等参数,所以想到用RedirectAttributes的addFlashAttribute 方式。但是重定向到/toLogin这个控制器里面的时候,获取不到addFlashAttribute 当初添加的属性。

具体事例:




//通过直接获取getFlashAttributes的map,然后获取带参,但是获取不到
Map<String, String> map=(Map<String, String>) attr.getFlashAttributes();
System.out.println(map.get("status"));
System.out.println(map.get("message"));

//addFlashAttribute 即将flashAttribute属性添加到request的OutputFlashMap中,以被重定向后的request获取
//所以我通过获取OutputFlashMap的方式来取值,却发现maps不为空,但是里面的参数没有
Map<String, Object> maps=RequestContextUtils.getOutputFlashMap(request);
System.out.println(maps.get("status"));
System.out.println(maps.get("message"));

//因为OutputFlashMap和InputFlashMap 都是由FlashMapManager来管理的
//对于每一次请求一个 “input” flash map 会被创建,来存储来自任何之前请求的
//flash attribute 还有一个 “output” flash map 会被创建,来存储任何我们存储在这个请求中的,之后的请求参数
//这里我获取getInputFlashMap,看看能不能获取到参数,但是还是map2直接为null
Map<String, String> map2=(Map<String, String>)RequestContextUtils.getInputFlashMap(request);
System.out.println(map2.get("status"));
System.out.println(map2.get("message"));

查了很多资料,包括看了spring mvc的官方文档,对于这个重定向之后参数怎么获取都没有什么明确的解释
包括上述三种方式,包括我直接获取参数的方式都不行,于是放弃了RedirectAttributes来传参


最后还是用session来解决,重定向之前设置session,重定向之后拿值移除session。

效果是做完了,但是心里一直纠结这个,所以发帖,看看各位能不能用RedirectAttributes的addFlashAttribute 方式,并且在另一个控制器里面获取这个添加的参数值

看在我光写这个帖子就花了这么久的份上,希望能得到答案...

...全文
52092 4 收藏 46
写回复
46 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
M_Kerry 2018-06-27
也许可以换个思路:
想把一个controller(A)的报错信息 传到另一个controller (B)
无非是两个原因
一是,我要B的返回页面
而是,我要B的处理逻辑
那么可不可以
在判断出来报错信息之后,
直接返回到Acontroller的 return的那个 页面
然后在复制一下在Acontroller里处理的逻辑。
这样就避免了 B的错误信息传不到A的尴尬
相当于在B里又加上了一个A的功能,当然
代价就是 代码有点冗余,如果A的处理逻辑代码很多,就显得有些臃肿。

但是 这样能够 把B的错误信息 传到 A返回jsp页面上。目的达到了。


这样的假设 是基于 我也没有尝试去找 到底有没有 一种方法,能够在A、B controller里能互传参数的方法。
回复
夏~ 2017-06-19
收藏了,另外使用jsonp共享数据也可以的
回复
bing_it 2017-04-28
forward
回复
顶一个~
回复
AshidaManasuki 2017-02-16
回复
JC_WorkSpace 2016-10-28
30楼的addFlashAttribute亲测有效!!
回复
叶芝殇 2016-09-30
30楼方法可用!addFlashAttribute中文没问题,addAttribute有乱码
回复
lionkang 2016-08-09
学习下。。。。。。
回复
zhaodongxx 2016-06-06
30楼,flash方法亲测可用。
回复
liu41259406 2016-06-06
引用 23 楼 hxyhlz 的回复:
Map<String, Object> modelMap = (Map<String, Object>)RequestContextUtils.getInputFlashMap(request);
回复
liu41259406 2016-06-06
23楼正解, 亲自试验了 完全好用
回复
II_Bat 2016-05-23
我的项目这样用是没有问题的
回复
II_Bat 2016-05-23
controller定义传递信息

    public String delete(@PathVariable("modelId") String modelId, RedirectAttributes redirectAttributes) {
        try {
            repositoryService.deleteModel(modelId);
            redirectAttributes.addFlashAttribute("message", "删除成功,模型ID=" + modelId);
        }catch (Exception e){
            logger.error("删除模型失败:modelId={}", modelId, e);
            redirectAttributes.addFlashAttribute("message", "删除失败,模型ID=" + modelId);
        }
        return "redirect:/bpm/model/index";
    }
页面获取定义信息

console.log("${message!}");
回复
king_1993 2016-03-04
引用 28 楼 nealkk 的回复:
//Map<String,?> map=attributes.getFlashAttributes(); //System.out.println(map.get("addreturn")); 这样是有数据的, 但是前台 <input type="hidden" id="addUserStatus" value="${addreturn}" />,el表达式却取不出来,是空的。 搜了很多页没有找到合适的答案,求助楼主。
你好,请问你取出来了吗
回复
wysxwdm 2016-02-03
可以通过一个中间页面,页面加载的时候自动提交表单到toLogin页面
回复
阿飞云 2015-12-13
上面的
return "redirect:/hello";
自己修改一下,跳转到自己制定的地址,刚才没有修改 失误
回复
阿飞云 2015-12-13
RedirectAttributes 的两个方式的获取总结: 1:addFlashAttribute
	
@RequestMapping(value="hello")
	public String test(RedirectAttributes ra){
		ra.addFlashAttribute("test", "test");
		return "redirect:/hello";
	}
	@RequestMapping(value="test")
	public String test(@ModelAttribute("test") String test){
		System.out.println(test);
		return "redirect:/hello";
	}
2:addAttribute

	@RequestMapping(value="hello")
	public String test(RedirectAttributes ra){
		ra.addAttribute("test", "test");
		return "redirect:/hello";
	}
	@RequestMapping(value="test")
	public String test(HttpServletRequest request
						/* ①:@ModelAttribute("test") String test*/ 
					     /*②:@RequestParam("test") String test*/){
		/*③:*/String test = request.getParameter("test");
		
		System.out.println(test);
		return "redirect:/hello";
	}
这就是获取到方式小实例代码,可以参考一下
回复
li930619 2015-12-08
回复
nealkk 2015-12-07
//Map<String,?> map=attributes.getFlashAttributes(); //System.out.println(map.get("addreturn")); 这样是有数据的, 但是前台 <input type="hidden" id="addUserStatus" value="${addreturn}" />,el表达式却取不出来,是空的。 搜了很多页没有找到合适的答案,求助楼主。
回复
nealkk 2015-12-07
楼主好,我新手,用了addFlashAttribute,但是前台却无法 取出数据。 controller中: attributes.addFlashAttribute("addreturn", "添加用户成功"); //确实加进去了
回复
加载更多回复
相关推荐
发帖
Java EE
创建于2007-09-28

6.6w+

社区成员

J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
申请成为版主
帖子事件
创建了帖子
2015-05-12 06:35
社区公告
暂无公告