关于重定向
一般情况下,控制器方法返回字符串类型的值会被当成逻辑视图名处理
如果返回的字符串中带 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:开头的返回值进行了特殊处理。即进行了请求转发和重定向的处理。