前言
SpringMVC 是目前主流的 Web MVC 框架之一。
如果有同学对它不熟悉,那么请参考它的入门 blog:http://www.cnblogs.com/fangjian0423/p/springMVC-introduction.html
本文所讲的部分内容跟 SpringMVC 的视图机制有关,SpringMVC 的视图机制请参考楼主的另一篇博客:
http://www.cnblogs.com/fangjian0423/p/springMVC-view-viewResolver.html
RedirectView 介绍
RedirectView 这个视图是跟重定向相关的,也是重定向问题的核心,我们来看看这个类的源码。
RedirectView 属性:
几个重要的构造方法:
RedirectView 渲染过程:
重点看来下路径的构造:
路径构造完毕之后使用 reponse 进行 sendRedirect 操作。
实例讲解
Controller 代码:
@Controller
@RequestMapping(value = "/redirect")
public class TestRedirectController {
@RequestMapping("/test1")
public ModelAndView test1() {
view.setViewName("redirect:index");
return view;
}
@RequestMapping("/test2")
public ModelAndView test2() {
view.setViewName("redirect:login");
return view;
}
@RequestMapping("/test3")
public ModelAndView test3(ModelAndView view) {
view.setViewName("redirect:/index");
return view;
}
@RequestMapping("/test4")
public ModelAndView test4(ModelAndView view) {
view.setView(new RedirectView("/index", false));
return view;
}
@RequestMapping("/test5")
public ModelAndView test5(ModelAndView view) {
view.setView(new RedirectView("index", false));
return view;
}
@RequestMapping("/test6/{id}")
public ModelAndView test6(ModelAndView view, @PathVariable("id") int id) {
view.setViewName("redirect:/index{id}"); view.addObject("test", "test");
return view;
}
@RequestMapping("/test7/{id}")
public ModelAndView test7(ModelAndView view, @PathVariable("id") int id) {
RedirectView redirectView = new RedirectView("/index{id}");
redirectView.setExpandUriTemplateVariables(false);
redirectView.setExposeModelAttributes(false);
view.setView(redirectView);
view.addObject("test", "test");
return view;
}
}
先看 test1 方法,返回值 "redirect:index" , 那么会使用重定向。
SpringMVC 找视图名 "redirect:index" 的时候,本文使用的 ViewResolver 是 FreeMarkerViewResolver。
FreeMarkerViewResolver 解析视图名的话,最调用父类之一的 UrlBasedViewResolver 中的 createView 方法。
通过构造方法发现,这个 RedirectView 使用相对路径,兼容 Http1.0,不暴露路径变量。
test1 方法,进入的路径:/SpringMVCDemo/redirect/test1。RedirectView 使用相对路径,那么重定向的路径: /SpringMVCDemo/redirect/index
我们通过 firebug 看下路径:
nice,验证了我们的想法。
test2 方法同理:进入的路径:/SpringMVCDemo/redirect/test2。 重定向的路径: /SpringMVCDemo/redirect/login。
test3 方法:以 "/" 开头并且使用相对路径,那么会默认加上 contextPath。 进入的路径:/SpringMVCDemo/redirect/test3。 重定向的路径: /SpringMVCDemo/index。
test4 方法:不使用默认路径,createTargetUrl 方法中直接 append "/index"。进入的路径:/SpringMVCDemo/redirect/test4。 重定向的路径: /index。
test5 方法:不使用默认路径,createTargetUrl 方法中直接 append "index"。进入的路径:/SpringMVCDemo/redirect/test5。 重定向的路径: /SpringMVCDemo/redirect/index。
其实这里有点意外,刚开始看的时候以为不使用绝对路径,以后路径会是 / SpringMVCDemo/index 或 / index。结果居然不是这样,感觉 SpringMVC 这个取名有点尴尬,有点蛋疼。其实 RedirectView 中的 createTargetUrl 方法就明白了,源码是最好的文档 0 0.
test6 方法:使用默认路径,该方法还使用了路径变量。本文之前分析的时候说了 RedirectView 中构造重定向路径的时候会对路径变量进行替代,还会暴露 model 中的属性,且这 2 个暴露分别受属性 expandUriTemplateVariables、exposeModelAttributes 影响,这 2 个属性默认都是 true。进入的路径:/SpringMVCDemo/redirect/test6/1。 重定向的路径: /SpringMVCDemo/index1?test=test。
test7 方法:跟 test6 方法一样,只不过我们不暴露 model 属性,不替代路径变量了。进入的路径:/SpringMVCDemo/redirect/test7/1。 重定向的路径: /SpringMVCDemo/index{id}。
总结
简单了分析了 RedirectView 视图,并分析了该视图的渲染源码,并分析了重定向中的路径问题,参数问题,路径变量问题等常用的问题。
源码真是最好的文档,了解了视图机制之后,再回过头来看看 RedirectView 视图,So easy。
最后感觉 RedirectView 的相对路径属性怪怪的,不使用相对路径,"/" 开头的直接就是服务器根路径, 不带 "/" 开头的,又是相对路径, 有点蛋疼。
希望本文能够帮助读者了解 SpringMVC 的重定向相关问题。
作者:format丶
来源链接:
https://www.cnblogs.com/fangjian0423/p/springMVC-redirectView-analysis.html