您的位置:首页 > 编程语言 > Java开发

springMvc的jsp视图解析

2015-03-24 16:28 351 查看
请求在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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息