使用springMVC 做重定向时,出现重定向 redirect 的问题
当我在程序中做重定向:
modelAndView.setViewName("redirect:" + "http://test.h5pay.jd.com/degrade?merchant=22318136&orderId=1177151445977076639213333333&sign=3d12b75777760135aa5771e88849d70a&aggregate=juhe");
return modelAndView;
时, 跳转到目标主机的controller时,获取到的相关参数为:
orderId=1177151445977076639213333333,QR777777777871
sign=3d12b75777760135aa5771e88849d70a,696196f2efe9e4b6c8cbc969d5ff26ff
其中我在程序中有赋值:
modelAndView.addObject("orderId", "QR777777777871");
modelAndView.addObject("sign", "696196f2efe9e4b6c8cbc969d5ff26ff");
原因:
spring MVC框架controller间跳转,需重定向,会将我modelAndView中放置的属性值,拼接到重定向url后导致
1. 需求背景
需求:spring MVC框架controller间跳转,需重定向。有几种情况:
不带参数跳转,
带参数拼接url形式跳转,
带参数不拼接参数跳转,页面也能显示。
传统的:可以通过在
redirect:select.do?id=""&name="";这样拼接来实现,也可以实现,但是如果参数中有中文,就会出现问题。
这里用它的addAttribute方法,这个实际上重定向过去以后你看url,是它自动给你拼了你的url。
他有两种带参的方式:
第一种:
attr.addAttribute("param", value);
这种方式就相当于重定向之后,在url后面拼接参数,这样在重定向之后的页面或者控制器再去获取url后面的参数就可以了,但这个方式因为是在url后面添加参数的方式,所以暴露了参数,有风险
例:
这样就相当于:return "redirect:/index?name=123&success=success"
第二种:
attr.addFlashAttribute("param", value);
这种方式也能达到重新向带参,而且能隐藏参数,其原理就是放到session中,session在跳到页面后马上移除对象。所以你刷新一下后这个值就会丢掉
例:
这种方式确实能重定向带参,但是有个问题,这个只能重定向到页面上,也就是说重定向的这个 页面视图,能用el表达式直接获取你带参的值,比如status 和message ,都能获取。 可是我重定向到另一个Controller的时候,这 个控制器里面没法获取这两个参数
我现在有个需求:登录成功,直接重定向其他页面,登录失败,又得重定向到登录页面,直接return的还不行,但是又要带状态码和提示等参数,所以想到用 RedirectAttributes的addFlashAttribute 方式。但是重定向到/toLogin这个控制器里面的时候,获取不到 addFlashAttribute 当初添加的属性。
具体事例:
查了很多资料,包括看了spring mvc的官方文档,对于这个重定向之后参数怎么获取都没有什么明确的解释
包括上述三种方式,包括我直接获取参数的方式都不行,于是放弃了RedirectAttributes来传参
最后还是用session来解决,重定向之前设置session,重定向之后拿值移除session。
效果是做完了,但是心里一直纠结这个,所以发帖,看看各位能不能用RedirectAttributes的addFlashAttribute 方式,并且在另一个控制器里面获取这个添加的参数值
我觉得可以使用modelAndView或者modelMap都可以解决吧
使用 redirectAttributes.getFlashAttributes();是取不到的 ;这地方要用request来取
public ModelAndView getItemList(HttpServletRequest request) {
Map<String, ?> map = RequestContextUtils.getInputFlashMap(request);
if (map != null) {
System.out.println(map.get("flashParams") + "这次终于取到啦");
}
}
这样就可以取到你想要的值啦
原文:https://my.oschina.net/u/2273085/blog/398374
spring MVC框架
controller间跳转
,需重定向。有几种情况:不带参数跳转,带参数拼接url形式跳转,带参数不拼接参数跳转,页面也能显示。
首先先来介绍一下不带参数的重定向:
我在后台一个controller跳转到另一个controller,为什么有这种需求呢,是这样的。我有一个列表页面,然后我会进行新增操作,新增在后台完成之后我要跳转到列表页面,不需要传递参数,列表页面默认查询所有的。
方式一:使用ModelAndView(这是Spring 2.0的时候所用到的方法)
return new ModelAndView("redirect:/toList");
这样可以重定向到toList这个方法
方式二:返回String
return "redirect:/ toList ";
注意: 重定向只能重定向到另一个请求中,如果需要直接跳转到页面中,直接通过
return "toList "; 类似于这种,跳转页面时,不能添加redirect ,除非是先跳转到另一次请求,再回到页面时
然后在说一下带参数的重定向
第二种情况,列表页面有查询条件,跳转后我的查询条件不能丢掉,这样就需要带参数的了,带参数可以拼接url
方式一:自己手动拼接url
new ModelAndView("redirect:/toList?param1="+value1+"¶m2="+value2);
这样有个弊端,就是传中文可能会有乱码问题。
方式二:用RedirectAttributes,这个是发现的一个比较好用的一个类
这里用它的addAttribute方法,这个实际上重定向过去以后你看url,是它自动给你拼了你的url。
使用方法:
public String test(RedirectAttributes attributes)
{
attributes.addAttribute("test", "hello");
return "redirect:/test/test2";
}
这样在toController这个方法中就可以通过获得参数的方式获得这个参数,再传递到页面。过去的url还是和方式一一样的。如果你细心的看重定向之后的url地址的话,你就会发现其实和上面的地址是一样的,这样也会出现上面那个方法出现的问题。
重点来了,
咱们介绍一个不会出现中文乱码
,而且不会在你的Url上出现你所要传递的数据的,这样就可以保证你在传递数据的安全
public String red(RedirectAttributes attributes)
{
attributes.addFlashAttribute("test", "hello");
return "redirect:/test/test2";
}
咱们用上面的方法进行数据传递你就会发现不会再Url上出现你要传递的数据,那么数据放到哪里去了,我
们就来看看这是Spring 3.0新出现的特性,attributes.addFlashAttribute("test", "hello")实际存储的属性在flashmap,那么flashmap又是什么呢?
Flash 属性 和 RedirectAttribute:通过FlashMap存储一个请求的输出,当进入另一个请求时作为该请求的输入,典型场景如重定向(POST- REDIRECT-GET模式,1、POST时将下一次需要的数据放在FlashMap;2、重定向;3、通过GET访问重定向的地址,此时 FlashMap会把1放到FlashMap的数据取出放到请求中,并从FlashMap中删除;从而支持在两次请求之间保存数据并防止了重复表单提 交)。
Spring Web MVC提供FlashMapManager用于管理FlashMap,默认使用SessionFlashMapManager,即数据默认存储在session中
既然知道了怎么回事,那么我们就可以把它提取出来,怎么提取呢,很多人会说,既然存在session中,那就从session中获取,结果发现没有,那怎么办?
下面我就给大家提供两个方法让大家把addFlashAttribute中的数据提取出来
方法一:利用httpServletRequest
public String test2(HttpServletRequest request)
{
Map<String,?> map = RequestContextUtils.getInputFlashMap(request);
System.out.println(map.get("test").toString());
return "/test/hello";
}
方法二:利用Spring提供的标签@ModelAttribute
public String test2(@ModelAttribute("test") String str)
{
System.out.println(str);
return "/test/hello";
}
详解SpringMVC重定向传参数的实现
本篇文章主要介绍了详解SpringMVC重定向传参数的实现,我们可以使用重定向的方式,改变浏览器的地址栏,防止表单因为刷新重复提交。有兴趣的可以了解一下。
在spring的一个controller中要把参数传到页面,只要配置视图解析器,把参数添加到Model中,在页面用el表达式就可以取到。但是,这样使用的是forward方式,浏览器的地址栏是不变的,如果这时候浏览器F5刷新,就会造成表单重复提交的情况。所以,我们可以使用重定向的方式,改变浏览器的地址栏,防止表单因为刷新重复提交。
jsp文件:
controller:
由于重定向相当于2次请求,所以无法把参数加在model中传过去。在上面例子中,页面获取不到msg参数。要想获取参数,可以手动拼url,把参数带在后面。
Spring 3.1 提供了一个很好用的类:RedirectAttributes。 使用这个类,我们可以把参数随着重定向传到页面,不需自己拼url了。
把上面方法参数中的Model换成RedirectAttributes,参数就自动跟在url后了。
但是,这样页面不能用el获取到,还要另外处理,所以,我们还有一种方式,不拼url,用el获取参数,就像普通转发一样。
还是使用RedirectAttributes,但是这次不用addAttribute方法,spring为我们准备了新方法,addFlashAttribute()。
这个方法原理是放到session中,session在跳到页面后马上移除对象。所以你刷新一下后这个值就会丢失。
这边我们使用@ModelAttribute注解,获取之前addFlashAttribute添加的数据,之后就可以正常使用啦。
需要例子代码的可以点此下载:
http://xiazai.jb51.net/201701/yuanma/springmvcdemo_jb51.rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
重定向:
(1)第一种情况:不需要传递参数。
方式一:使用ModelAndView
return new ModelAndView("redirect:/toList");
这样可以重定向到toList这个方法
方式二:返回String
return "redirect:/ toList ";
(2)第二种情况:带参数
拼接url,用RedirectAttributes,这里用它的addAttribute方法,这个实际上重定向过去以后你看url
,是它自动给你拼了你的url。
使用方法:
attr.addAttribute("param", value);
return "redirect:/namespace/toController";
这样在toController这个方法中就可以通过获得参数的方式获得这个参数,再传递到页面。
不拼接url:
@RequestMapping("/save")
public String save(@ModelAttribute("form") Bean form,
RedirectAttributes attr
)
throws Exception {
String code = service.save(form);
if(code.equals("000")){
attr.addFlashAttribute
("name", form.getName());
attr.addFlashAttribute("success", "添加成功!");
return "redirect:/index";
}else{
attr.addAttribute
("projectName", form.getProjectName());
attr.addAttribute("enviroment", form.getEnviroment());
attr.addFlashAttribute("msg", "添加出错!");
return "redirect:/maintenance/toAddConfigCenter";
}
}
注意:1.使用RedirectAttributes的addAttribute方法传递参数会跟随在URL后面,如上代码即为
http:/index.action?a=a
2.
使用addFlashAttribute不会跟随在URL后面,会把该参数值暂时保存于session,
待重定向url获取该参数后从session中移除,
这里的redirect必须是方法映射路径,jsp无效
。你会
发现redirect后的jsp页面中b只会出现一次,刷新后b再也不会出现了,这验证了上面说的,b被访问
后就会从session中移除。对于重复提交可以使用此来完成.
另外,如果使用了RedirectAttributes作为参数,但是没有进行redirect呢?这种情况下不会
将RedirectAttributes参数传递过去,默认传forward对应的model,官方的建议是:
p:ignoreDefaultModelOnRedirect="true" />
设置下RequestMappingHandlerAdapter 的ignoreDefaultModelOnRedirect属性,这样可以提高效率
,避免不必要的检索。
当保存POJO到数据库后,要返回成功页面,如果这个时候要带点信息,则要这样:
@RequestMapping(value = "/user/save", method = RequestMethod.POST)
public ModelAndView saveUser(UserModel user, RedirectAttributes redirectAttributes)
throws Exception {
redirectAttributes.addFlashAttribute("message", "保存用户成功!");//使用
addFlashAttribute,参数不会出现在url地址栏中
return "redirect:/user/save/result";
}
转发:
返回ModelAndView :
@RequestMapping(value="/test",method=RequestMethod.GET)
public ModelAndView testForward(ModelAndView model){
model.setViewName("forward:index.jsp");
return model;
}
如上代码,如果返回modelAndView 则可以如红色标注,添加forward即可,若想重定向,可把
forward替换成redirect便可达到目的。
返回String:
@RequestMapping(value="/forward",method=RequestMethod.GET)
public String testForward(){
return "forward:/index.action";
}