这两个我按照个人理解画了一张图,利用这张图去理解可能会好点,如有错误或不恰当之处,请及时指正,谢谢:-)
从上图可以看出重定向是游览器(客户端)行为,而内部转发是服务器行为。还有就是重定向是全程使用的是两个request,和两个response。而内部转发是使用的一个request和response。
然后关于重定向不能传参的解决办法(这个是借鉴于https://www.cnblogs.com/zhujiabin/p/4935557.html):
在springmvc3.1版本出来了一个小功能(RedirectAttributes)可以实现。有两种方式:
attr.addAttribute("param", value);
attr.addFlashAttribute("param", value);
这两点的区别:
第一个就类似于地址传参即在url后拼接参数,下面是案例:
public String demo(RedirectAttributes attr) {
attr.addAttribute("name", "123");
attr.addAttribute("success", "success");
return "redirect:/index";
}
上面的代码等同于:
public String demo() {
return "redirect:/index?name=123&success=success"
}
这种方式的风险在于参数直接暴露在地址栏了。
第二种的原理是通过将参数放置在session中,达到传参并隐藏参数的目的。但是好像会在跳转到页面后会移除这个对象,即刷新后这个参数就会丢失。
另外,对于什么时候使用重定向还是内部转发:
- 访问的路径是web应用外部时,只能使用重定向
- 访问的路径时web应用内部时,可根据需要选择,毕竟重定向会改变地址栏,而内部转发地址栏是不会变化的,且虽说springmvc现在出了重定向带参的功能,但是目前需要传参时还是建议使用转发。可能有一些情况必须得使用重定向而不是内部转发,后面遇到会补充,如果看到此处的兄弟碰到过这种情况,希望您留言一下,我好补充一下哈哈。
补充
1
目前在写SpringBoot博客时,发现了一个问题,我使用重定向后不能访问重定向的html,只能访问到重定向后的哪个url对应的Controller,而转发只能访问html,不能访问该url对应的Controller,找了找百度和询问别人之后,emm,三个解答:
- 我的配置出错了
- 重定向一定不会经过视图解析器,因为请求转发的页面是在地址栏直接访问的,是一个新的请求,如果经过视图解析器,拼接后的结果就是错误的,所以重定向一定不经过视图解析器。另外WEB-INF下的所有文件必须通过请求转发才能访问。
- 加了forward或redirect后不会拼接视图解析器的前后缀了,由于默认为转发,所以转发(不显示声明forward)可以拼接视图解析器,如果手动加了,则只会匹配Controller了,找不到就报404
个人目前感觉可能是第二个和第三个,当然第一个也有可能,在适当的配置下应该也能完成重定向访问到资源。
对于第二个我自己的理解是重定向(客户端总共两次请求)相当于又让游览器的地址栏输入了一个请求,自然不能加前缀后缀,加了就不一定是原来的请求了。所以访问的只能是地址栏中url对应的Controller。
对于第三个,我自己确实自己手动测试了,如果显式得加上forward,也会导致不会添加视图解析器的前后缀,而重定向必须显式加redirect,所以自然不会添加前后缀了。
2
还有必须使用重定向的一个地方是访问某个页面前必须进行某些操作,则得使用重定向转到其他Controller进行某些操作。