springMvc的jsp视图解析

请求在org.springframework.web.servlet.DispatcherServlet#doDispatch通过HandlerExecutionChain的解析得到ModelAndView这个mv,然后会交给processDispatchResult方法来看一下是否有异常处理,得到最终的mv,然后调用render方法;

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()) {
		//如果mv不包含有视图对象,那么就要去解析视图.
		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() + "'");
		}
	}
	else {
		//不需要查找,直接从mv对象拿到View实例
		view = mv.getView();
		if (view == null) {
			throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +
					"View object in servlet with name '" + getServletName() + "'");
		}
	}

	// Delegate to the View object for rendering.
	if (logger.isDebugEnabled()) {
		logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");
	}
	try {
	//对视图进行渲染
		view.render(mv.getModelInternal(), request, response);
	}
	catch (Exception ex) {
		if (logger.isDebugEnabled()) {
			logger.debug("Error rendering view [" + view + "] in DispatcherServlet with name '" +
					getServletName() + "'", ex);
		}
		throw ex;
	}
}

protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
		HttpServletRequest request) throws Exception {
	//viewResolvers是所有的视图解析器集合,按顺序去解析,一旦有一个视图解析器能解析,直接返回.
	for (ViewResolver viewResolver : this.viewResolvers) {
		View view = viewResolver.resolveViewName(viewName, locale);
		if (view != null) {
			return view;
		}
	}
	return null;
}
经过上面得到了View实例,再去调用view.render(mv.getModelInternal(), request, response);
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
	if (logger.isTraceEnabled()) {
		logger.trace("Rendering view with name '" + this.beanName + "' with model " + model +
			" and static attributes " + this.staticAttributes);
	}
	//使用一个Map来装model数据
	Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);
	prepareResponse(request, response);
	renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);
}
如果配置的是jsp视图,就会紧跟着调用org.springframework.web.servlet.view.InternalResourceView#renderMergedOutputModel
@Override
protected void renderMergedOutputModel(
		Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {

	//将model数据暴露为request的属性(通过request.setAttribute(modelName, modelValue))
	exposeModelAsRequestAttributes(model, request);

	// Expose helpers as request attributes, if any.
	exposeHelpers(request);

	//获取分发路径
	String dispatcherPath = prepareForRendering(request, response);

	//为目标资源(比较典型的是JSP)构建一个RequestDispatcher对象(rd已经是javax.servlet的api,与spring mvc没多大关系,剩下的工作也主要由servlet容器完成).
	RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath);
	if (rd == null) {
		throw new ServletException("Could not get RequestDispatcher for [" + getUrl() +
				"]: Check that the corresponding file exists within your web application archive!");
	}

	// If already included or response already committed, perform include, else forward.
	if (useInclude(request, response)) {
		response.setContentType(getContentType());
		if (logger.isDebugEnabled()) {
			logger.debug("Including resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
		}
		rd.include(request, response);
	}

	else {
		// Note: The forwarded resource is supposed to determine the content type itself.
		if (logger.isDebugEnabled()) {
			logger.debug("Forwarding to resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
		}
		//分发
		rd.forward(request, response);
	}
}


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值