這兩天遇到一個需求:在請求action時,校驗一下簽名的有效性。爲了作到統一,在一處地方作校驗而不是分散在各個action裏作,就用到了攔截器。我的以爲spring mvc中的攔截器和asp.net裏面的HttpModule很是相似,均可以在請求在匹配到action以前作攔截。其餘的很少說,直接上乾貨。html
這篇講基於java config的攔截器的實現,具體怎麼作呢,其實很是簡單,只要兩步就能夠完成,最後我會附上源代碼:java
第一步:自定義攔截器。具體來講就是寫一個實現HandlerInterceptor接口的類,這個接口有三個方法,三個方法的執行時機不一樣,能夠根據本身的需求看看實現哪個。web
@Component public class SystemInterceptor implements HandlerInterceptor { org.slf4j.Logger logger = LoggerFactory.getLogger("interceptor"); /** * preHandle方法是進行處理器攔截用的,顧名思義,該方法將在Controller處理以前進行調用, * SpringMVC中的Interceptor攔截器是鏈式的,能夠同時存在多個Interceptor, * 而後SpringMVC會根據聲明的先後順序一個接一個的執行, * 並且全部的Interceptor中的preHandle方法都會在Controller方法調用以前調用。 * SpringMVC的這種Interceptor鏈式結構也是能夠進行中斷的, * 這種中斷方式是令preHandle的返回值爲false,當preHandle的返回值爲false的時候整個請求就結束了。 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HandlerMethod handlerMethod = (HandlerMethod) handler; logger.error("攔截的Controller:"+handlerMethod.getBeanType().getName()); logger.error("攔截的action:"+handlerMethod.getMethod().getName()); return true; } /** * 這個方法只會在當前這個Interceptor的preHandle方法返回值爲true的時候纔會執行。 * postHandle是進行處理器攔截用的,它的執行時間是在處理器進行處理之 後, 也就是在Controller的方法調用以後執行, * 可是它會在DispatcherServlet進行視圖的渲染以前執行,也就是說在這個方法中你能夠對ModelAndView進行操做。 * 這個方法的鏈式結構跟正常訪問的方向是相反的,也就是說先聲明的Interceptor攔截器該方法反而會後調用, * 這跟Struts2裏面的攔截器的執行過程有點像, * 只是Struts2裏面的intercept方法中要手動的調用ActionInvocation的invoke方法, * Struts2中調用ActionInvocation的invoke方法就是調用下一個Interceptor或者是調用action, * 而後要在Interceptor以前調用的內容都寫在調用invoke以前,要在Interceptor以後調用的內容都寫在調用invoke方法以後。 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } /** * 該方法也是須要當前對應的Interceptor的preHandle方法的返回值爲true時纔會執行。 * 該方法將在整個請求完成以後,也就是DispatcherServlet渲染了視圖執行, 這個方法的主要做用是用於清理資源的, */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
第二步:註冊自定義攔截器。這一步是基於《基於JavaConfig配置的Spring MVC的構建》完成的,so,請先看下這篇文章,而後就會明白這一切都那麼簡單~~。這裏就一個方法,看一下就明白了,就只說下addPathPatterns的做用,這個方法的做用就是過濾請求的path,只有符合條件的請求path纔會被攔截。spring
@Configuration @EnableWebMvc @ComponentScan("com.deepbatis.web") public class WebConfig extends WebMvcConfigurerAdapter { /*配置視圖解析器*/ @Bean public ViewResolver viewResolver(){ InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/pages/"); resolver.setSuffix(".jsp"); resolver.setExposeContextBeansAsAttributes(true); return resolver; }
/*註冊攔截器*/ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new SystemInterceptor()).addPathPatterns("/*"); } /*配置靜態資源的處理*/ @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } }
最後,跑一下程序就知道是怎麼回事了,老樣子,放源碼: 攔截器的源碼在這裏mvc