`
yaerfeng1989
  • 浏览: 232512 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Spring MVC拦截器配置及其原理分析

阅读更多

原创整理不易,转载请注明出处:Spring MVC拦截器配置及其原理分析

代码下载地址:http://www.zuidaima.com/share/1751865167973376.htm

SpringMVC的拦截器不同于Spring的拦截器,SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServlet,所以只需要在DispatcherServlet上做文章即可,DispatcherServlet也没有代理,同时SpringMVC管理的Controller也不有代理。

一、Servlet Filter与Spring interceptor的执行顺序

Filter有顺序吗?我们怎么控制filter的执行顺序。通过Tomcat的代码分析,servlet在Filter执行完成后才调用,如有多个filter怎么控制执行顺序,首先会想到在web.xml配置某个参数,例如order之类的,但查找一下一番,servlet并没有这个参数。试试filter Mapping的配置的先后顺序,果然有效,原来filter的执行顺序就考filter mapping在web.xml中的顺序。

spring interceptor也是这样的执行顺序,不过interceptor多一个配置参数order通过他也可以来实现interceptor的执行顺序。很多应用场景中,执行顺序还是重要的,比如cache和transaction interceptor的执行顺序,很显然cache应该在transaction之前,这样发现命中了就不用打开事务,如果transaction在前,每次都打开事务即使cache命中,这是一个无谓东动作。

二、利用springMVC的interceptor实现页面性能监控(Filter亦可)

调优第一步,找出耗时比较长的页面进行优化。利用interceptor能轻易搞定。interceptor提供了preHandle和postHandle以及afterCompletion三个方法。preHandle调用controller具体方法之前调用,postHandle完成具体方法之后调用,afterCompletion完成对页面的render以后调用,至此整个页面渲染完成。也就是说我们在preHandle记录开始的时间,在afterCompletion记录结束的时间,就可或者整个页面生成的时间。Spring自带StopWatch工具类来实现时间跟踪,关键一点interceptor不是线程安全的。我们需要借助threadlocal来实现线程安全。

@Override 
public boolean preHandle(HttpServletRequest request, 
		HttpServletResponse response, Object handler) throws Exception { 
	if(usePerformance){ 
		StopWatch stopWatch = new StopWatch(handler.toString()); 
		stopWatchLocal.set(stopWatch); 
		stopWatch.start(handler.toString()); 
	} 
	 
	return true; 
} 

@Override 
public void afterCompletion(HttpServletRequest request, 
		HttpServletResponse response, Object handler, Exception ex) 
		throws Exception { 
	if(usePerformance){ 
		StopWatch stopWatch = stopWatchLocal.get(); 
		stopWatch.stop(); 
		String currentPath = request.getRequestURI(); 
		String queryString  = request.getQueryString(); 
		queryString = queryString == null ? "":"?" + queryString; 
		log.info("access url path:" + currentPath + queryString +  " |time:" + stopWatch.getTotalTimeMillis()); 
		stopWatchLocal.set(null); 
	} 
} 
 

三、SpringMVC 拦截器实现分析

SpringMVC的拦截器不同于Spring的拦截器,SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServlet,所以只需要在DispatcherServlet上做文章即可,DispatcherServlet也没有代理,同时SpringMVC管理的Controller也不有代理。哪不难想到我们在执行controller之前做某些动作,执行完毕做某些动作,render完成做某些动作。SpringMVC的拦截器对应提供了三个preHandle,postHandle,afterCompletion方法。只需在三个方法内写我们需要的逻辑就行,多了都是废话,还是代码实在。 

 

如果你没有使用springMVC可以使用filter来完成:

stopWatch.start(); 
doFilterChain(); 
stopWatch.stop(); 

三、SpringMVC 拦截器实现分析

SpringMVC的拦截器不同于Spring的拦截器,SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServlet,所以只需要在DispatcherServlet上做文章即可,DispatcherServlet也没有代理,同时SpringMVC管理的Controller也不有代理。哪不难想到我们在执行controller之前做某些动作,执行完毕做某些动作,render完成做某些动作。SpringMVC的拦截器对应提供了三个preHandle,postHandle,afterCompletion方法。只需在三个方法内写我们需要的逻辑就行,多了都是废话,还是代码实在。

HandlerInterceptor[] interceptors = mappedHandler.getInterceptors(); 
if (interceptors != null) { 
	for (int i = 0; i < interceptors.length; i++) { 
		HandlerInterceptor interceptor = interceptors[i]; 
//ha.handle是调用具体的controller在此之前执行preHandle                      if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) { 
			triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null); 
			return; 
		} 
		interceptorIndex = i; 
	} 
} 

// Actually invoke the handler. 
mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); 

完成调用之后,调用render(),最后执行afterCompletion()。

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

// Trigger after-completion for successful outcome. 
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);  
3
4
分享到:
评论

相关推荐

    Spring MVC使用Demo

    为了实现这些功能,Spring MVC的配置文件(如servlet-context.xml)需要正确配置组件扫描、视图解析器、拦截器等。不过,现代Spring MVC项目往往倾向于使用Java配置或Spring Boot的自动配置,减少了XML的使用。 在...

    spring mvc 参数绑定漏洞

    5. **使用参数绑定拦截器**:创建自定义拦截器,对请求参数进行预处理,过滤或修正不合法的输入。 此外,开发者还应关注Spring的安全更新,及时升级Spring MVC框架以修补已知的安全漏洞。通过结合代码审查、单元...

    《精通Spring MVC 4》源码

    源码中可以发现它如何处理请求映射、拦截器链以及异常处理。 Controller接口是Spring MVC中的关键角色,它定义了业务逻辑和视图之间的交互。开发者通常会实现这个接口或使用@Controller注解的类来处理请求。在源码...

    Spring MVC Beginner’s Guide 源代码

    - **servlet-context.xml**:Spring MVC的核心配置文件,声明拦截器、视图解析器、bean等。 3. **处理器映射器与适配器** - **HandlerMapping**:负责将URL映射到对应的处理器(Controller)方法。 - **...

    spring mvc框架源码

    在本源码分析中,我们将探讨Spring MVC的工作原理、主要组件及其交互方式。 1. **DispatcherServlet**: 作为Spring MVC的前端控制器,DispatcherServlet是所有请求的入口点。它负责拦截请求,根据请求信息(如URL、...

    看透spring mvc源代码分析与实践扫描版带目录+源码

    8. **Interceptor(拦截器)**:Spring MVC允许定义拦截器,它们在请求处理前后执行,可用于权限检查、日志记录等功能。 9. **注解驱动开发**:Spring MVC支持使用注解来简化配置,如@RequestMapping、@Controller...

    【面试资料】-(机构内训资料)看透Spring MVC源代码分析与实践.zip

    - Spring MVC的AOP在Web层的应用,如过滤器和拦截器的异同。 - 深入源码,例如DispatcherServlet的doDispatch方法,以及HandlerExecutionChain的处理流程。 这份资料可能涵盖以上各个方面,通过学习和理解,可以...

    Spring MVC示例

    此外,还有Spring的配置文件如`applicationContext.xml`或`dispatcher-servlet.xml`,用于配置Spring MVC的Bean,如视图解析器、处理器映射器、拦截器等。 3. **定时器(Timer)功能**: 提供的定时器功能可能使用了...

    精通spring mvc 4 看透springmvc pdf 高清完全版

    接着,深入探讨了Spring MVC的高级特性,例如:拦截器(Interceptor)用于在请求处理前后执行自定义逻辑,视图解析器(ViewResolver)用于确定响应的视图,以及数据绑定和验证机制,这些能帮助开发者实现更灵活的...

    Spring MVC源码深度剖析开源架构源码2021.pdf

    本知识点将围绕Spring MVC的源码深度剖析展开,详细介绍Spring MVC的源码结构、工作原理以及如何进行源码分析。 首先,要理解Spring MVC是如何启动和配置的。在web.xml文件中配置了DispatcherServlet,这是Spring ...

    Spring MVC入门(登录示例)

    **Spring MVC 入门教程——基于登录示例** Spring MVC 是 Spring 框架的一个模块,主要用于构建 Web...随着经验的增长,你可以逐步引入更多的功能,如拦截器、数据绑定、异常处理等,进一步提升应用的复杂性和健壮性。

    SpringMVC拦截器例子详解

    下面将详细解释Spring MVC拦截器的工作原理、配置和实际应用。 1. **工作原理**: - 拦截器是基于AOP(面向切面编程)思想实现的,它通过预处理器和后处理器模式,对HTTP请求进行拦截。 - 当一个请求到达Spring ...

    spring mvc 快速入门深入分析

    - **配置拦截器**:在`mvc.xml`中配置拦截器。 #### 十、全局异常处理 Spring MVC 提供了一种机制来处理全局异常,可以通过实现`HandlerExceptionResolver`接口或使用`@ControllerAdvice`配合`@ExceptionHandler`...

    SpringMVC拦截器源代码.zip

    Spring MVC 是一个基于Java的轻量级Web应用框架,它为构建...通过对压缩包中的源代码进行分析和学习,你可以深入理解Spring MVC拦截器的工作原理,掌握如何根据需求自定义拦截器,从而提高应用程序的功能性和可维护性。

    Spring MVC资料

    Spring框架的核心组件之一,Spring MVC旨在简化开发,提供诸如数据验证、本地化、拦截器等功能,使得开发者可以更专注于业务逻辑。 在描述中提到的"SpringMVC",意味着我们将深入探讨这个框架的关键概念和用法。...

    看透Spring MVC源代码分析与实践

    分析拦截器的源代码,有助于我们掌握如何在Spring MVC中增加自定义逻辑。 7异常处理:Spring MVC提供了多种方式来处理异常,如@ExceptionHandler注解,整个异常处理的机制在源代码层面是如何实现的,是值得深入探索...

    SpringMVC学习(十二)——SpringMVC中的拦截器

    在本篇文章中,我们将深入探讨Spring MVC中的拦截器机制,了解其工作原理、如何配置以及实际应用场景。 首先,我们来解释一下什么是拦截器。在Web应用开发中,拦截器是一种设计模式,它可以对请求进行预处理和后...

    传智播客Spring MVC课程源码

    9. **MVC配置**:Spring MVC的配置可以通过XML或Java配置,包括视图解析器、拦截器、数据绑定等设置。 10. **拦截器(Interceptor)**:可以自定义拦截器实现请求预处理和后处理,例如登录检查、性能监控等。 11. ...

    spring MVC 基本应用

    通过分析这些文件,你可以更好地理解 Spring MVC 的工作原理和配置方式。 总的来说,Spring MVC 提供了一种结构化的 web 应用开发方式,结合 Eclipse 的强大支持,可以让开发者高效地构建健壮的、可扩展的应用程序...

Global site tag (gtag.js) - Google Analytics