Spring MVC知识点整理
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:*-context.xml</param-value>
</context-param>
<servlet>
<servlet-name>platform-services</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:platform-services-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

/**
* Process the actual dispatching to the handler.
* <p>The handler will be obtained by applying the servlet's HandlerMappings in order.
* The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters
* to find the first that supports the handler class.
* <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers
* themselves to decide which methods are acceptable.
* @param request current HTTP request
* @param response current HTTP response
* @throws Exception in case of any kind of processing failure
*/
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null ;
int interceptorIndex = -1; try {
ModelAndView mv;
boolean errorView = false; try {
processedRequest = checkMultipart(request); // Determine handler for the current request.
mappedHandler = getHandler(processedRequest, false);
if ( mappedHandler == null || mappedHandler.getHandler() == null ) {
noHandlerFound( processedRequest, response);
return;
} // Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler .getHandler()); // Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = "GET".equals( method);
if ( isGet || "HEAD".equals( method)) {
long lastModified = ha.getLastModified( request, mappedHandler.getHandler());
if ( logger.isDebugEnabled()) {
String requestUri = urlPathHelper.getRequestUri(request );
logger.debug( "Last-Modified value for [" + requestUri + "] is: " + lastModified);
}
if ( new ServletWebRequest( request, response).checkNotModified( lastModified) && isGet) {
return;
}
}
1. 在handler执行之前,获取注册到相关handler的interceptor列表,调用的顺序与配置的顺序一致
// Apply preHandle methods of registered interceptors.
HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
if ( interceptors != null) {
for ( int i = 0; i < interceptors. length; i++) {
HandlerInterceptor interceptor = interceptors[ i];
if (!interceptor.preHandle(processedRequest , response , mappedHandler.getHandler())) {
2. 如果interceptor.preHandle执行结果为false,则触发afterCompletion方法的调用,并直接返回
triggerAfterCompletion( mappedHandler, interceptorIndex , processedRequest, response , null);
return;
}
interceptorIndex = i;
}
} // Actually invoke the handler.
mv = ha.handle( processedRequest, response, mappedHandler.getHandler()); // Do we need view name translation?
if ( mv != null && ! mv.hasView()) {
mv.setViewName(getDefaultViewName( request));
}
3. handler执行完业务逻辑处理后,逆序调用interceptor列表来执行postHandle方法
// Apply postHandle methods of registered interceptors.
if ( interceptors != null) {
for ( int i = interceptors. length - 1; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[ i];
interceptor.postHandle( processedRequest, response, mappedHandler.getHandler(), mv );
}
}
}
catch (ModelAndViewDefiningException ex) {
logger.debug( "ModelAndViewDefiningException encountered" , ex);
mv = ex.getModelAndView();
}
catch (Exception ex) {
Object handler = ( mappedHandler != null ? mappedHandler.getHandler() : null );
mv = processHandlerException(processedRequest , response , handler , ex);
errorView = ( mv != null);
} // Did the handler return a view to render?
if ( mv != null && ! mv.wasCleared()) {
render( mv, processedRequest, response);
if ( errorView) {
WebUtils. clearErrorRequestAttributes(request);
}
}
else {
if ( logger.isDebugEnabled()) {
logger.debug( "Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +
"': assuming HandlerAdapter completed request handling");
}
}
4. 完成视图的渲染之后,触发interceptor的afterCompletion方法,逆序执行
// Trigger after-completion for successful outcome.
triggerAfterCompletion( mappedHandler, interceptorIndex, processedRequest , response , null);
} catch (Exception ex) {
5. 触发Exception后,执行interceptor的afterCompletion方法
// Trigger after-completion for thrown exception.
triggerAfterCompletion( mappedHandler, interceptorIndex, processedRequest , response , ex );
throw ex;
}
catch (Error err) {
ServletException ex = new NestedServletException("Handler processing failed" , err );
// Trigger after-completion for thrown exception.
triggerAfterCompletion( mappedHandler, interceptorIndex, processedRequest , response , ex );
throw ex;
} finally {
// Clean up any resources used by a multipart request.
if ( processedRequest != request) {
cleanupMultipart( processedRequest);
}
}
}
<mvc:interceptors >
<bean class= "com.interceptor.test.authenInterceptor" >
<property name ="excludeUris">
<list >
<value >/static/ </value >
</list >
</property >
</bean >
</mvc:interceptors >

.png)
<bean name="/hello.htm" class="com.sina.controller.HelloController"/> <bean name="/sayHello*" class="com.sina.controller.HelloController"/>
SimpleUrlHandlerMapping相对于BeanNameUrlHandlerMapping的优势在与不需要为一个类重复定义bean,而且XML的可读性也更强,其配置实例如下:
<bean id="helloController" class="com.sina.controller.HelloController"/> <bean id="urlHandler" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<map>
<entry key="/hello.htm" value-ref="helloController"/>
<entry key="/sayHello*" value-ref="helloController"/>
<entry key="/welcome.html" value-ref="helloController"/>
<entry key="/welcomeUser*" value-ref="helloController"/>
</map>
</property>
</bean>
/**
* Initialize the HandlerMappings used by this class.
* <p>If no HandlerMapping beans are defined in the BeanFactory for this namespace,
* we default to BeanNameUrlHandlerMapping.
*/
private void initHandlerMappings (ApplicationContext context) {
this. handlerMappings = null; if ( this. detectAllHandlerMappings) {
//1. 如果detectAllHandlerMappings,则找到所有注册的HandlerMapping bean
Map<String, HandlerMapping> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors( context, HandlerMapping.class, true , false);
if (! matchingBeans.isEmpty()) {
this. handlerMappings = new ArrayList<HandlerMapping>(matchingBeans .values());
//2. 对handlerMappings进行排序,排序依据是注册时的order值
OrderComparator.sort(this.handlerMappings);
}
}
//3. 如果detectAllHandlerMappings为false,则只查找名称为HandlerMapping的bean。
else {
try {
HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME , HandlerMapping.class);
this. handlerMappings = Collections.singletonList(hm);
}
catch ( NoSuchBeanDefinitionException ex) {
// Ignore, we'll add a default HandlerMapping later.
}
} // Ensure we have at least one HandlerMapping, by registering
// a default HandlerMapping if no other mappings are found.
4. 如果没有在上下文找到一个HandlerMapping bean,则采用默认策略加载,具体策略设置可以在 DispatcherServlet.properties中看到
if ( this. handlerMappings == null) {
this. handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
if ( logger.isDebugEnabled()) {
logger.debug( "No HandlerMappings found in servlet '" + getServletName() + "': using default");
}
}
}
HandlerAdapter的作用是调用HandlerMapping映射好的处理类和方法,具体配置方式和初始化流程与HandlerMapping相似。
HandlerExceptionResolver接口让开发者可以对异常进行处理,返回给调用者更友好、清晰的信息。

public final void init()
throws ServletException
{
if(logger.isDebugEnabled())
logger.debug((new StringBuilder()).append("Initializing servlet '").append(getServletName()).append("'").toString());
try
{
org.springframework.beans.PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), requiredProperties);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
org.springframework.core.io.ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
bw.registerCustomEditor(org/springframework/core/io/Resource, new ResourceEditor(resourceLoader, getEnvironment()));
initBeanWrapper(bw);
bw.setPropertyValues(pvs, true);
}
catch(BeansException ex)
{
logger.error((new StringBuilder()).append("Failed to set bean properties on servlet '").append(getServletName()).append("'").toString(), ex);
throw ex;
}
initServletBean();
if(logger.isDebugEnabled())
logger.debug((new StringBuilder()).append("Servlet '").append(getServletName()).append("' configured successfully").toString());
}
Spring MVC知识点整理的更多相关文章
- Spring MVC 知识点整理
		
extend:http://www.jianshu.com/p/bef0e52067d2 1. Redis 存储方式 Redis存储机制分成两种Snapshot 和 AOF.无论是那种机制,Redis ...
 - 2019年Spring核心知识点整理,看看你掌握了多少?
		
前言 如今做Java尤其是web几乎是避免不了和Spring打交道了,但是Spring是这样的大而全,新鲜名词不断产生,学起来给人一种凌乱的感觉,在这里总结一下,理顺头绪. Spring 概述 Spr ...
 - [Java] Spring MVC 知识点
		
云图: @Service 用于标注业务层组件. 在 Spring-servlet 配置xml中,component-scan 标签默认情况下自动扫描指定路径下的包(含所有子包),将带有@Compone ...
 - Spring MVC面试整理
		
Spring MVC执行过程 客户端的请求提交到dispatcherServlet DispatcherServlet查询一个或者多个handlermapping ,找请求的Controller Di ...
 - Spring mvc知识点总结——面试篇
		
一.MVC思想MVC(Model-View-Controller)三元组的概念:1.Model(模型):数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数 ...
 - Spring重要知识点整理
		
一.IOC(Inversion of Control):控制反转 (1)Spring Core最核心部分 (2)需要先了解依赖注入(Denpendency Injection)/把底层类作为参数传递给 ...
 - spring MVC 异常处理整理
		
一.异常结构 1.异常由外到内如下: web服务器处理异常--->web应用里面web.xml处理异常--->Spring框架处理异常---->控制器注释处理异常--->控制器 ...
 - Spring MVC 知识点记忆
		
1.Dao 用的 @Repository 2.Handler 用的 @Controller 3. @Autowired 消除了对get set方法 4. @RequestMapping(value= ...
 - spring mvc 注解整理(一)
		
@Controller和@RestController: RestController = @ResponseBody + @Controller 所有返回都是json类型,无法跳转到jsp页面,但 ...
 
随机推荐
- scope引起的问题
			
背景 执行mvn clean test命令提示部分包不存在,但通过eclipse的clean操作后可以执行mvn test命令 解决方法 mvn clean操作为清空编译的class文件,test的话 ...
 - 50个Java多线程面试题(上)
			
Java 语言一个重要的特点就是内置了对并发的支持,让 Java 大受企业和程序员的欢迎.大多数待遇丰厚的 Java 开发职位都要求开发者精通多线程技术并且有丰富的 Java 程序开发.调试.优化经验 ...
 - 输入输出系统--I/O接口
			
计算机组成原理\硬件结构\输入输出系统\I/O接口 一.概述 接口可以看做是两个系统或两个部件之间的交接部分,它即可以是两种硬设备之间的连接电路,也可以是两个软件之间共同的逻辑边界. I/O接口通常是 ...
 - Git 初学
			
记录git与远成仓库建立连接日志 gitbub上创建远程仓库 https://github.com/ 创建登陆账号进入主页 , 选择右上角的加号 新建rep Repository name 为你创建的 ...
 - poj 1182 食物链 带权并查集
			
食物链是并查集的进阶运用的一道非常经典的题目. 题目如下: 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A, ...
 - 解决VS2015中没有报表项(ReportViewer)的方法
			
作者:何时.微笑成了种奢求 VS2015中没有报表项(ReportViewer),怎么办?这篇文章主要为大家详细介绍了解决VS2015中没有报表项(ReportViewer)的方法,感兴趣的小伙伴们可 ...
 - python2.x与3.x的主要区别笔记
			
#coding:utf-8 ''' python3.x新的东西 目录 使用__future__模块 print函数 整数除法 Unicode xrange 触发异常 处理异常 next()函数和.ne ...
 - macaca  测试web(3)
			
上回书说到 macaca 测试web(2) 使用ddt做参数驱动化, 有些人会说,你好low,我说怎么low呢,他说你看看你的脚本就放在一个文件里,对于我们小白来说,这看起来很乱啊,能不能给我拆分, ...
 - 设置Linux环境变量的方法与区别(Ubuntu)
			
设置 Linux 环境变量可以通过 export 实现,也可以通过修改几个文件来实现,有必要弄清楚这两种方法以及这几个文件的区别. 通过文件设置 Linux 环境变量 首先是设置全局环境变量, ...
 - 面向对象五大原则(SRP、OCP、LSP、DIP、ISP)
			
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt173 OO的五大原则是指 1. SRP(Single Responsibil ...