文档章节

spring MVC工作机制与设计模式-读后小结(三)

bosscheng
 bosscheng
发布于 2013/05/16 15:00
字数 1115
阅读 1372
收藏 19

Control的调用(续)

接着对于(二)的补充:主要是小结下Control的处理逻辑的关键操作;

对于control的处理关键就是:DispatcherServlet的handlerMappings集合中根据请求的URL匹配每一个handlerMapping对象中的某个handler,匹配成功之后将会返回这个handler的处理连接handlerExecutionChain对象。而这个handlerExecutionChain对象中将会包含用户自定义的多个handlerInterceptor对象。

/**
	 * Return the HandlerExecutionChain for this request.
	 * <p>Tries all handler mappings in order.
	 * @param request current HTTP request
	 * @return the HandlerExecutionChain, or <code>null</code> if no handler could be found
	 */
	protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		for (HandlerMapping hm : this.handlerMappings) {
			if (logger.isTraceEnabled()) {
				logger.trace(
						"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
			}
			HandlerExecutionChain handler = hm.getHandler(request);
			if (handler != null) {
				return handler;
			}
		}
		return null;
	}
而对于handlerInterceptor接口中定义的三个方法中,preHandler和postHandler分别在handler的执行前和执行后执行,afterCompletion在view渲染完成、在DispatcherServlet返回之前执行。

PS:这么我们需要注意的是:当preHandler返回false时,当前的请求将在执行完afterCompletion后直接返回,handler也将不会执行。

在类HandlerExecutionChain中的getHandler()方法是返回object对象的;

/**
	 * Return the handler object to execute.
	 * @return the handler object
	 */
	public Object getHandler() {
		return this.handler;
	}
这里的handler是没有类型的,handler的类型是由handlerAdapter决定的。dispatcherServlet会根据handler对象在其handlerAdapters集合中匹配哪个HandlerAdapter实例支持该对象。接下来去执行handler对象的相应方法了,如果该handler对象的相应方法返回一个ModelAndView对象接下来就是去执行View渲染了。

/**
	 * Return the handler object to execute.
	 * @return the handler object
	 */
	public Object getHandler() {
		return this.handler;
	}

---------------------------------------邪恶的分割线---------------------------------------------

Model设计

如果handler兑现返回了ModelAndView对象,那么说明Handler需要传一个Model实例给view去渲染模版。除了渲染页面需要model实例,在业务逻辑层通常也有Model实例。


ModelAndView对象是连接业务逻辑层与view展示层的桥梁,对spring MVC来说它也是连接Handler与view的桥梁。ModelAndView对象顾名思义会持有一个ModelMap对象和一个View对象或者View的名称。ModelMap对象就是执行模版渲染时候所需要的变量对应的实例,如jsp的通过request.getAttribute(String)获取的JSTL标签名对应的对象。velocity中context.get(String)获取$foo对应的变量实例。

public class ModelAndView {

/** View instance or view name String */
	private Object view;

	/** Model Map */
	private ModelMap model;

	/** Indicates whether or not this instance has been cleared with a call to {@link #clear()} */
	private boolean cleared = false;

.....

}

ModelMap其实也是一个Map,Handler中将模版中需要的对象存在这个Map中,然后传递到view对应的ViewResolver中。

public interface ViewResolver {
	View resolveViewName(String viewName, Locale locale) throws Exception;

}

不同的ViewResolver会对这个Map中的对象有不同的处理方式;

  • velocity中将这个Map保存到VelocityContext中。
  • JSP中将每一个ModelMap中的元素分别设置到request.setAttribute(modelName,modelValue);

-----------------------邪恶的分割线-----------------------------------------------

view设计

在spring MVC中,view模块需要两个组件来支持:RequestToViewNameTranslator和ViewResolver

public interface RequestToViewNameTranslator {

	/**
	 * Translate the given {@link HttpServletRequest} into a view name.
	 * @param request the incoming {@link HttpServletRequest} providing
	 * the context from which a view name is to be resolved
	 * @return the view name (or <code>null</code> if no default found)
	 * @throws Exception if view name translation fails
	 */
	String getViewName(HttpServletRequest request) throws Exception;

}
对于 ViewResolver,前面有写到了,就不写了;

-----------------------邪恶的分割线-------------------------------------------------

RequestToViewNameTranslator:主要支持用户自定义对viewName的解析,如将请求的ViewName加上前缀或者后缀,或者替换成特定的字符串等。

ViewResolver:主要是根据用户请求的viewName创建适合的模版引擎来渲染最终的页面,ViewResolver会根据viewName创建一个view对象,调用view对象的Void render方法渲染出页面;

public interface View {
void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;
}
下面来总结下 Spring MVC解析View的逻辑:

  • dispatcherServlet方法调用getDefaultViewName()方法;

/**
	 * Translate the supplied request into a default view name.
	 * @param request current HTTP servlet request
	 * @return the view name (or <code>null</code> if no default found)
	 * @throws Exception if view name translation failed
	 */
	protected String getDefaultViewName(HttpServletRequest request) throws Exception {
		return this.viewNameTranslator.getViewName(request);
	}
  • 调用了RequestToViewNameTranslator的getViewName方法;

public interface RequestToViewNameTranslator {

	/**
	 * Translate the given {@link HttpServletRequest} into a view name.
	 * @param request the incoming {@link HttpServletRequest} providing
	 * the context from which a view name is to be resolved
	 * @return the view name (or <code>null</code> if no default found)
	 * @throws Exception if view name translation fails
	 */
	String getViewName(HttpServletRequest request) throws Exception;

}

  • 调用LocaleResolver接口的resolveLocale方法;

Locale resolveLocale(HttpServletRequest request);
  • 调用ViewResolver接口的resolveViewName方法,返回view对象

View resolveViewName(String viewName, Locale locale) throws Exception;
  • 调用render方法渲染出页面



© 著作权归作者所有

bosscheng
粉丝 80
博文 303
码字总数 95443
作品 0
南京
前端工程师
私信 提问
现代Java进阶之路必备技能——2019 版

Java技术的学习阶段有三 第1个是java基础,比如对集合类,并发,IO,JVM,内存模型,泛型,异常,反射,等有深入了解。 第2个是全面的互联网技术相关知识,比如redis,mogodb,nginx,代码自...

Java小仙女
03/26
0
0
java 设计模式用了哪些

看到有个面试题:除了使用单例模式,你在项目中还使用了什么设计模式? 我仔细想了下,貌似真的就只是用了单例模式. 我用的spring MVC+ mybaties开发电商.

小小丁灬
2016/09/06
725
11
Spring框架中的设计模式(四)​

Spring框架中的设计模式(四) 本文是Spring框架中使用的设计模式第四篇。本文将在此呈现出新的3种模式。一开始,我们会讨论2种结构模式:适配器和装饰器。在第三部分和最后一部分,我们将讨...

瑞查德-Jack
2018/07/20
89
0
Spring框架中的设计模式(三)

Spring框架中的设计模式(三) 原创: 瑞查德-Jack 在之前的两篇文章中,我们看到了一些在Spring框架中实现的设计模式。这一次我们会发现这个流行框架使用的3种新模式。 本文将从描述两个创意...

瑞查德-Jack
2018/07/19
111
0
Java面似宝典--Java Web(JSP、Servlet、各常用框架SSH、MyBatis等)

1、什么MVC模式?说说你对MVC的理解。 2、工作中经常用到的框架有哪些?它们各自的优缺点是什么? 3、说说Struts、Spring中的设计模式。 4、拦截器和过滤器两者的区别是什么? 5、简述一下,...

瓜子葫芦侠
2014/03/26
32
0

没有更多内容

加载失败,请刷新页面

加载更多

CSS--列表

一、列表标识项 list-style-type none:去掉标识项 disc:默认实心圆 circle:空心圆 squire:矩形 二、列表项图片 list-style-img: 取值:url(路径) 三、列表项位置 list-style-position:...

wytao1995
今天
8
0
linux 命令-文本比较comm、diff、patch

本文原创首发于公众号:编程三分钟 今天学了三个文本比较的命令分享给大家。 comm comm 命令比较相同的文本 $ cat charabc$ cat chardiffadc 比如,我有两个文件char和chardiff如上,...

编程三分钟
今天
9
0
QML教程

https://blog.csdn.net/qq_40194498/article/category/7580030 https://blog.csdn.net/LaineGates/article/details/50887765...

shzwork
今天
7
0
HA Cluster之5

对于使用heartbeat v2版的CRM配置的集群信息都是保存在一个名为cib.xml的配置文件中,存放在/var/lib/heartbeat/crm/下。CIB:Cluster Information Base,由于xml文件配置不是那么方便,所以...

lhdzw
今天
8
0
玩转Redis-Redis基础数据结构及核心命令

  《玩转Redis》系列文章主要讲述Redis的基础及中高级应用,文章基于Redis5.0.4+。本文主要讲述Redis的数据结构String,《玩转Redis-Redis基础数据结构及核心命令》相关操作命令为方便对比...

zxiaofan666
今天
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部