前面讲解了View和InternalViewResource
本节课讲述另外一个RedirectView
用于页面跳转的
首先我们需要了解请求的跳转会在浏览器中修改请求链接,这样跳转的请求和原请求就是两个不相干的请求,跳转的请求会丢失掉原请求的中的所有数据,一般的解决方法是将原请求中的数据放到跳转请求的链接中这样来获取数据。
首先当返回值为"redirect:get.action"时,会调用ViewNameMethodReturnValueHandler的handleReturnValue方法,判断是否是跳转页面,设置跳转标记
ViewNameMethodReturnValueHandler中的实现如下:
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
if (returnValue instanceof CharSequence) {
String viewName = returnValue.toString();
mavContainer.setViewName(viewName);
//用于判断是否是跳转页面 redirect
if (isRedirectViewName(viewName)) {
mavContainer.setRedirectModelScenario(true);
}
}
else if (returnValue != null){
// should not happen
throw new UnsupportedOperationException("Unexpected return type: " +
returnType.getParameterType().getName() + " in method: " + returnType.getMethod());
}
}
当判断页面是跳转页面是ViewResolver生成的View对象是RedirectView,这样就可以实现页面跳转工作了。
接下来我们看看在RedirectView中所做的操作,最终的实现是在renderMergedOutputModel中完成实现的,这边需要实现的机制是在连接重定向时数据会丢失,这样使用FlashMap将数据保存起来作为重定向后的数据使用。
@Override
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
HttpServletResponse response) throws IOException {
//创建跳转链接
String targetUrl = createTargetUrl(model, request);
targetUrl = updateTargetUrl(targetUrl, model, request, response);
//获取原请求所携带的数据
FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request);
if (!CollectionUtils.isEmpty(flashMap)) {
UriComponents uriComponents = UriComponentsBuilder.fromUriString(targetUrl).build();
flashMap.setTargetRequestPath(uriComponents.getPath());
flashMap.addTargetRequestParams(uriComponents.getQueryParams());
FlashMapManager flashMapManager = RequestContextUtils.getFlashMapManager(request);
if (flashMapManager == null) {
throw new IllegalStateException("FlashMapManager not found despite output FlashMap having been set");
}
//将数据保存起来,作为跳转之后请求的数据使用
flashMapManager.saveOutputFlashMap(flashMap, request, response);
}
//重定向操作
sendRedirect(request, response, targetUrl, this.http10Compatible);
}
简单来说RedirectView实现了链接的重定向,并且将数据保存到FlashMap中,这样在跳转后的链接中可以获取一些数据