Spring MVC RedirectAttributes的用法

执笔记忆的空白
博客专家认证
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 方式,并且在另一个控制器里面获取这个添加的参数值

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

...全文
52464 46 打赏 收藏 转发到动态 举报
写回复
用AI写文章
46 条回复
切换为时间正序
请发表友善的回复…
发表回复
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", "添加用户成功"); //确实加进去了
加载更多回复(24)
[ 2021年,将Spring全家桶的课程进行Review,确保不再有顺序错乱等问题导致学员看不懂内容,进入2022年,将Spring的课程进行整理,整理为案例精讲的系列课程,并开始逐步增加高阶的Spring Security等内容,课件将逐步进行上传,敬请期待! ]本课程是Spring全家桶案例精讲课程的第二部分Spring MVCSpring案例精讲课程以真实场景、项目实战为导向,循序渐进,深入浅出的讲解Java网络编程,助力您在技术工作中更进一步。 本课程聚焦Java Spring的Web知识点,主要是关于Spring MVC的应用,包含:表单的增删改查、国际化、过滤器、拦截器、日志Log4j2及slf4j的使用、主题更改网站皮肤及样式、文件上传等的案例讲解,并且最后以一个SSM(Spring+Spring MVC+Mybatis)贯穿前后台的案例作为Spring MVC课程的终奖, 从而使大家快速掌握Spring的基础核心知识,快速上手,为面试、工作等做好充足准备。 由于本课程聚焦于案例,即直接上手操作,对于Spring的原理等不会做过多介绍,希望了解原理等内容的需要通过其他视频或者书籍去了解,建议按照该案例课程一步步做下来,之后再去进一步回顾原理,这样能够促进大家对原理有更好的理解。 【通过Spring全家桶,我们保证你能收获到以下几点】 1、掌握Spring全家桶主要部分的开发、实现2、可以使用Spring MVCSpring Boot、Spring Cloud及Spring Data进行大部分的Spring开发3、初步了解使用微服务、了解使用Spring进行微服务的设计实现4、奠定扎实的Spring技术,具备了一定的独立开发的能力  【实力讲师】 毕业于清华大学软件学院软件工程专业,曾在Accenture、IBM等知名外企任管理及架构职位,近15年的JavaEE经验,近8年的Spring经验,一直致力于架构、设计、开发及管理工作,在电商、零售、制造业等有丰富的项目实施经验 【本课程适用人群】如果你是一定不要错过!  适合于有JavaEE基础的,如:JSP、JSTL、Java基础等的学习者没有基础的学习者跟着课程可以学习,但是需要补充相关基础知识后,才能很好的参与到相关的工作中。 【Spring全家桶课程共包含如下几门】 

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧