springmvc處理重定向或者轉發的返回值

 

springmvc支持直接在返回字符串上申明該視圖是轉發或者是重定向

@RequestMapping(value="/taoge")
	public String taogetest(HttpServletRequest request,Model model){
		return "forward:toregister";
        # return "redirect:toregister";
	}

這兩種方式都能完成control之間的跳轉,它們具體是怎麼實現的呢

主要是在DispatcherServlet.render(ModelAndView, HttpServletRequest, HttpServletResponse) line: 1234 上

/**
	 * Render the given ModelAndView.
	 * <p>This is the last stage in handling a request. It may involve resolving the view by name.
	 * @param mv the ModelAndView to render
	 * @param request current HTTP servlet request
	 * @param response current HTTP servlet response
	 * @throws ServletException if view is missing or cannot be resolved
	 * @throws Exception if there's a problem rendering the view
	 */
	protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
		// Determine locale for request and apply it to the response.
		Locale locale = this.localeResolver.resolveLocale(request);
		response.setLocale(locale);

		View view;
		if (mv.isReference()) {  #判斷當前view名是否是可用的,如果不能直接用,那麼需要解析該視圖名
			// We need to resolve the view name.
			view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request); #這個方法是真正解析視圖的方法
			if (view == null) {
				throw new ServletException("Could not resolve view with name '" + mv.getViewName() +
						"' in servlet with name '" + getServletName() + "'");
			}
		}

DispatcherServlet.resolveViewName(String, Map<String,Object>, Locale, HttpServletRequest) line: 1296    
 

protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
			HttpServletRequest request) throws Exception {

		for (ViewResolver viewResolver : this.viewResolvers) {
			View view = viewResolver.resolveViewName(viewName, locale);
			if (view != null) {
				return view;
			}
		}
		return null;
	}

 InternalResourceViewResolver(AbstractCachingViewResolver).resolveViewName(String, Locale) line: 145    

	public View resolveViewName(String viewName, Locale locale) throws Exception {
		if (!isCache()) { 是否存在緩存
			return createView(viewName, locale);
		}
		else {
			Object cacheKey = getCacheKey(viewName, locale); 從緩存中取出對應的鍵
			View view = this.viewAccessCache.get(cacheKey);
			if (view == null) { 如果在緩存map還是找不到該視圖,那麼就重新生成一個
				synchronized (this.viewCreationCache) {
					view = this.viewCreationCache.get(cacheKey);
					if (view == null) {
						// Ask the subclass to create the View object.
						view = createView(viewName, locale); 重新生成一個視圖
						if (view == null && this.cacheUnresolved) {
							view = UNRESOLVED_VIEW;
						}
						if (view != null) {
							this.viewAccessCache.put(cacheKey, view);
							this.viewCreationCache.put(cacheKey, view);
							if (logger.isTraceEnabled()) {
								logger.trace("Cached view [" + cacheKey + "]");
							}
						}
					}
				}
			}
			return (view != UNRESOLVED_VIEW ? view : null);
		}
	}

 UrlBasedViewResolver類中453行

@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. 判斷是否存在前置字符串redirect:
		if (viewName.startsWith(REDIRECT_URL_PREFIX)) {
			String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length());
			RedirectView view = new RedirectView(redirectUrl, isRedirectContextRelative(), isRedirectHttp10Compatible());
			view.setHosts(getRedirectHosts());
			return applyLifecycleMethods(viewName, view);
		}
		// Check for special "forward:" prefix.
		if (viewName.startsWith(FORWARD_URL_PREFIX)) { 判斷是否存在前置字符串forward:
			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);
	}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章