`
xifei321
  • 浏览: 20343 次
  • 性别: Icon_minigender_1
  • 来自: 无锡
文章分类
社区版块
存档分类
最新评论

SpringMVC DispatcherServlet的viewResolvers初始化

阅读更多


一、ViewResolver 接口
public interface ViewResolver {
//通过给定的名字解析返回View对象
View resolveViewName(String viewName, Locale locale) throws Exception;
}



二、InternalResourceViewResolver ViewResolver 实现类

public class InternalResourceViewResolver extends UrlBasedViewResolver {
//判断jstl类是否存在
private static final boolean jstlPresent = ClassUtils.isPresent("javax.servlet.jsp.jstl.core.Config", InternalResourceViewResolver.class.getClassLoader());
.........


public InternalResourceViewResolver() {
//实例创建时,默认使用InternalResourceView作为View
Class viewClass = requiredViewClass();
if (viewClass.equals(InternalResourceView.class) && jstlPresent) {
//如果JSTL API存在则使用JstlView作为View
	viewClass = JstlView.class;
		}
setViewClass(viewClass);
	}





UrlBasedViewResolver InternalResourceViewResolver 的父类

支持AbstractUrlBasedView的子类如:InternalResourceView、VelocityView、FreeMarkerView 可以通过该类的viewClass属性注入。
视图名称可以是资源的URL,或者通过指定prefix 和suffix组合成url
prefix="/WEB-INF/jsp/", suffix=".jsp", viewname="test" ->
"/WEB-INF/jsp/test.jsp"
redirect:myAction.do 重定向到指定action,不会当视图名称解析。
forward:myAction.do请求转发。


public class UrlBasedViewResolver extends AbstractCachingViewResolver implements Ordered {
//有对应的setter和getter方法
private Class viewClass;
private String prefix = "";
private String suffix = "";
.....


//父类AbstractCachingViewResolver实现了ViewResolver接口,在实现该接口resolveViewName方法是调用了createView(viewName, locale);
@Override
protected View createView(String viewName, Locale locale) throws Exception {
                  if (!canHandle(viewName, locale)) {
			return null;
		}
//视图名前缀redirect:返回会重定向视图
if (viewName.startsWith(REDIRECT_URL_PREFIX)) {
String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length());
return new RedirectView(redirectUrl, isRedirectContextRelative(), isRedirectHttp10Compatible());

}
//视图名前缀forward:请求转发处理view
if (viewName.startsWith(FORWARD_URL_PREFIX)) {
String forwardUrl = viewName.substring(FORWARD_URL_PREFIX.length());
return new InternalResourceView(forwardUrl);
}
//普通视图名称解析生成View		
 return super.createView(viewName, locale);
}

//根据视图名加载View对象
@Override
protected View loadView(String viewName, Locale locale) throws Exception {
AbstractUrlBasedView view = buildView(viewName);
View result = (View) getApplicationContext().getAutowireCapableBeanFactory().initializeBean(view, viewName);
return (view.checkResource(locale) ? result : null);
}

//根据指定的视图名创建View的实例,并配置。这个view对象不会被spring容器的生命周期方法管理。
子类会首先调用super.buildView(viewName)也就是这个方法,然后再设置其他属性。
protected AbstractUrlBasedView buildView(String viewName) throws Exception {
AbstractUrlBasedView view = (AbstractUrlBasedView) BeanUtils.instantiateClass(getViewClass());
view.setUrl(getPrefix() + viewName + getSuffix());
String contentType = getContentType();
if (contentType != null) {
	view.setContentType(contentType);
}
view.setRequestContextAttribute(getRequestContextAttribute());
view.setAttributesMap(getAttributesMap());
return view;
	}
}



======================================================================
三、View对象创建完成,JstlView作为View对象render渲染过程
(View在SpringMVC中作用)
3.1 View接口

public interface View {
//命名响应状态  
  String RESPONSE_STATUS_ATTRIBUTE = View.class.getName() + ".responseStatus";
//根据给定的model渲染视图。
//第一步:预处理请求,在jsp中,就是将modle中的对象设置到请求属性中。
//第二步:实际的渲染处理,如包含一个JSP通过RequestDispatcher的include方法
void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;
}


3.2 AbstractView 抽象类对View接口render方法实现

public abstract class AbstractView extends WebApplicationObjectSupport implements View, BeanNameAware {

......

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);
}

//结合model
Map<String, Object> mergedModel =
new HashMap<String, Object>(this.staticAttributes.size() + (model != null ? model.size() : 0));
mergedModel.putAll(this.staticAttributes);
if (model != null) {
mergedModel.putAll(model);
}


if (this.requestContextAttribute != null) {
mergedModel.put(this.requestContextAttribute, createRequestContext(request, response, mergedModel));
}
//预处理响应
prepareResponse(request, response);
//实际渲染过程在InternalResourceView子类中实现。
renderMergedOutputModel(mergedModel, request, response);
}



protected void prepareResponse(HttpServletRequest request, HttpServletResponse response) {
		if (generatesDownloadContent()) {
			response.setHeader("Pragma", "private");
			response.setHeader("Cache-Control", "private, must-revalidate");
		}
	}



//将模型设置为request的属性
protected void exposeModelAsRequestAttributes(Map<String, Object> model, HttpServletRequest request) throws Exception {
for (Map.Entry<String, Object> entry : model.entrySet()) {
	String modelName = entry.getKey();
	Object modelValue = entry.getValue();
	if (modelValue != null) {
	request.setAttribute(modelName, modelValue);
if (logger.isDebugEnabled()) {
logger.debug("Added model object '" + modelName + "' of type [" + modelValue.getClass().getName() +
							"] to request in view with name '" + getBeanName() + "'");
				}
			}
			else {
		request.removeAttribute(modelName);
	if (logger.isDebugEnabled()) {
logger.debug("Removed model object '" + modelName +
"' from request in view with name '" + getBeanName() + "'");
				}
			}
		}
	}
....
}


3.3 AbstractView 的子类InternalResourceView




protected void renderMergedOutputModel(
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {

//判断是否需要返回一个包装后的request对象
HttpServletRequest requestToExpose = getRequestToExpose(request);

//将model对象设置为request的属性
exposeModelAsRequestAttributes(model, requestToExpose);

//由子类JstlView实现,绑定spring或local资源文件
exposeHelpers(requestToExpose);

//获取请求的url地址 
String dispatcherPath = prepareForRendering(requestToExpose, response);

// 获取RequestDispatcher 对象
RequestDispatcher rd = requestToExpose.getRequestDispatcher(dispatcherPath);
if (rd == null) {
throw new ServletException(
"Could not get RequestDispatcher for [" + getUrl() + "]: check that this file exists within your WAR");
}


if (useInclude(requestToExpose, response)) {
response.setContentType(getContentType());
if (logger.isDebugEnabled()) {
logger.debug("Including resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
			}
rd.include(requestToExpose, response);
}

else {

exposeForwardRequestAttributes(requestToExpose);
if (logger.isDebugEnabled()) {
logger.debug("Forwarding to resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
}
rd.forward(requestToExpose, response);
}



protected HttpServletRequest getRequestToExpose(HttpServletRequest originalRequest) {
		if (this.exposeContextBeansAsAttributes || this.exposedContextBeanNames != null) {
//返回Request的包装类,作用是在调用request的getAttribute方法时先从WebApplicationContext中找定义的bean对象,如果没有才从request对象中取属性
也就是将webApplicationContext容器中的bean作为request中的属性对象,暴露给的RequestDispatcher(请求转发到JSP页面转换成的servlet时可以从request中获取Ioc定义的bean或handle处理后的model对象)
return new ContextExposingHttpServletRequest(
originalRequest, getWebApplicationContext(), this.exposedContextBeanNames);
		}
		return originalRequest;
	}


}




















分享到:
评论

相关推荐

    Spring框架系列(13) - SpringMVC实现原理之DispatcherServlet的初始化过程.doc

    SpringMVC DispatcherServlet 初始化过程详解 DispatcherServlet 是 SpringMVC 框架中的核心组件,对于 SpringMVC 的请求处理和响应起着至关重要的作用。DispatcherServlet 的初始化过程是 SpringMVC 实现原理的...

    SpringMVC源码剖析(三)- DispatcherServlet的初始化流程1

    在本文中,我们将深入探讨`DispatcherServlet`的初始化流程,这是SpringMVC的核心组件。`DispatcherServlet`扮演着中央调度者的角色,负责接收请求、解析请求信息,并调用合适的控制器进行业务逻辑处理。 首先,让...

    SpringMVC DispatcherServlet重写、自定义拦截器拦截器源码

    SpringMVC DispatcherServlet重写、自定义拦截器拦截器源码

    SpringMVC DispatcherServlet组件实现解析

    在 DispatcherServlet 的 init() 方法中,除了初始化 SpringIOC 容器外,还会初始化一些 SpringMVC 组件,包括: * MultipartResolver:处理multipart请求 * LocaleResolver:处理语言环境 * ThemeResolver:处理...

    Spring源码学习九:DispatcherServlet初始化源码分析1

    DispatcherServlet是SpringMVC的核心分发器,它实现了请求分发,是处理请求的入口,本篇将深入源码分析它的初始化过程。 首先,从DispatcherServlet的名称上可以看出它是一个Servlet,通过一张图来看一下它的实现...

    浅谈springmvc的DispatcherServlet分析

    同时,我们还指定了初始化参数contextConfigLocation,用于加载SpringMVC的配置文件spring-mvc.xml。 二、SpringMVC的配置文件 在SpringMVC的配置文件spring-mvc.xml中,我们需要配置controller的扫描路径和视图...

    Spring MVC启动时初始化的几个常用方法

    1. **加载配置**:`DispatcherServlet`会在初始化阶段读取配置文件(如`servlet-context.xml`),通过`WebApplicationContext`加载Bean定义。这个过程中,你可以自定义拦截器、视图解析器、异常处理器等关键组件。 ...

    从源码的角度来看SpringMVC.pdf

    8. initViewResolvers:初始化ViewResolvers来解析视图。 9. initFlashMapManager:初始化FlashMapManager来管理跨请求的属性。 在处理请求时,DispatcherServlet首先从HandlerMappings中提取对应的Handler。...

    SpringMVC 处置流程分析

    总结,SpringMVC的处置流程始于Web应用的初始化,包括ContextLoaderListener加载根上下文和DispatcherServlet初始化子上下文。接着,DispatcherServlet负责接收和分发请求,通过HandlerMapping找到处理器,...

    SpringMVC URL 与 Controller 方法 初始化 源码赏析.vsdx

    SpringMVC URL 与 Controller 方法初始化源码流程 Visio 文档 文档可以直接通过Visio进行编辑,方便二次修改、学习

    welcome-file-list 与SpringMvc 的 DispatcherServlet

    在SpringMVC中 所有的请求都由dispatcherServlet处理(url-pattern配置的是/),当配置文件中有对静态资源的处理  时候 ,先匹配 welcome-file-list 中的文件,依次查找,找到了就 返回,如果没有找到就继续匹配到...

    SpringMVC 初始化 URL 与 Controller 方法 流程源码.vsdx

    SpringMVC URL 与 Controller 方法初始化源码流程 Visio 文档 文档可以直接通过Visio进行编辑,方便二次修改、学习

    Spring和SpringMVC父子容器关系

    SpringMVC中的DispatcherServlet在初始化时,会创建一个属于自己的ApplicationContext,我们通常称之为子容器。这个子容器负责处理与SpringMVC相关的bean,如Controller、ViewResolver、HandlerMapping等。...

    03springmvc注解驱动开发的servlet3.0初始化配置类.avi

    03springmvc注解驱动开发的servlet3.0初始化配置类.avi

    springMVC练手代码

    在`hou_job_springmvc2`或`hou_spring_mvc2`项目中,你可能会找到对应的配置文件(如`web.xml`),里面会定义DispatcherServlet的初始化参数。 2. **配置文件**:SpringMVC的配置通常在XML文件(如`servlet-context...

    SpringMVC+Hibernate+Spring整合实例

    首先,Spring会初始化并管理所有组件,包括SpringMVC的DispatcherServlet、Controller以及Hibernate的SessionFactory。然后,当用户发起HTTP请求时,DispatcherServlet捕获请求并转发给相应的Controller。Controller...

    SpringMVC入门案例源码

    这些文件定义了DispatcherServlet的初始化参数,控制器的映射,视图解析器等。 3. **@Controller注解**:标记在类上,表示该类为SpringMVC的控制器,处理来自客户端的请求。控制器中的方法通过@RequestMapping注解...

    SpringMVC入门最简洁工程

    `web.xml`是应用的部署描述符,用于配置前端控制器DispatcherServlet和SpringMVC的初始化参数。`spring-servlet.xml`是SpringMVC的核心配置文件,用于定义处理器映射器、视图解析器以及其他Bean。 **3. 最少的Jar包...

Global site tag (gtag.js) - Google Analytics