关于重定向
一般情况下,控制器方法返回字符串类型的值会被当成逻辑视图名处理
如果返回的字符串中带 forward: 或 redirect: 前缀时,SpringMVC 会对他们进行特殊处理:
将 forward: 和redirect: 当成指示符,其后的字符串作为 URL 来处理
redirect:success.jsp:会完成一个到 success.jsp 的重定向的操作
forward:success.jsp: 会完成一个到 success.jsp 的转发操作
示例
1. 添加请求handler
/** * 类定义处标记的@RequestMapping 限定了处理器类可以处理所有 URI 为 /user 的请求,它相对于 WEB 容器部署的根路径 * * @author RabbitX */ @Controller @SessionAttributes(value={"user","time"},types={String.class}) @RequestMapping("/user") public class UserController { /** * 请求转发和重定向之转发 * */ @RequestMapping("/testForward") public String testForward() { System.out.println("--------------testForward----------------"); return "forward:/pages/login.jsp"; } /** * 请求转发和重定向之重定向 * */ @RequestMapping("/testRedirect") public String testRedirect() { System.out.println("--------------testRedirect----------------"); return "redirect:/pages/login.jsp"; } }
2. 添加jsp内容
<li><a href="user/testForward">请求转发和重定向之转发</a></li> <li><a href="user/testRedirect">请求转发和重定向之重定向</a></li>
原理分析
1. 在UserController的testForward或testRedirect方法中添加断点调试;
2. 启动调试
在调试栈中选中:DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse) line: 945
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
进入上面代码后面的方法processDispatchResult:
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
进入上面方法内的方法render:
render(mv, request, response);
进入上面方法内的方法resolveViewName:
view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
进入上面方法内的方法resolveViewName:
View view = viewResolver.resolveViewName(viewName, locale);
进入方法resolveViewName时,选择类AbstractCachingViewResolver
进入类AbstractCachingViewResolver的方法resolveViewName中的方法createView:
return createView(viewName, locale);
或者
view = createView(viewName, locale);
进入方法createView时,选择实现类UrlBasedViewResolver
@Override protected View createView(String viewName, Locale locale) throws Exception { // If this resolver is not supposed to handle the given view, // return null to pass on to the next resolver in the chain. if (!canHandle(viewName, locale)) { return null; } // Check for special "redirect:" prefix. if (viewName.startsWith(REDIRECT_URL_PREFIX)) { String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length()); RedirectView view = new RedirectView(redirectUrl, isRedirectContextRelative(), isRedirectHttp10Compatible()); return applyLifecycleMethods(viewName, view); } // Check for special "forward:" prefix. if (viewName.startsWith(FORWARD_URL_PREFIX)) { String forwardUrl = viewName.substring(FORWARD_URL_PREFIX.length()); return new InternalResourceView(forwardUrl); } // Else fall back to superclass implementation: calling loadView. return super.createView(viewName, locale); }
阅读此段代码,可以知道SpringMVC对以redirect:和forward:开头的返回值进行了特殊处理。即进行了请求转发和重定向的处理。