1. 程式人生 > >基於JavaConfig配置的攔截器使用

基於JavaConfig配置的攔截器使用

mint obj apt ole 靜態資源 中斷 context 資源 作用

  這兩天遇到一個需求:在請求action時,校驗一下簽名的有效性。為了做到統一,在一處地方做校驗而不是分散在各個action裏做,就用到了攔截器。個人覺得spring mvc中的攔截器和asp.net裏面的HttpModule非常類似,都可以在請求在匹配到action之前做攔截。其他的不多說,直接上幹貨。

  這篇講基於java config的攔截器的實現,具體怎麽做呢,其實非常簡單,只要兩步就可以完成,最後我會附上源代碼:

  第一步:自定義攔截器。具體來說就是寫一個實現HandlerInterceptor接口的類,這個接口有三個方法,三個方法的執行時機不同,可以根據自己的需求看看實現哪一個。

@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才會被攔截。

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

  技術分享

  最後,跑一下程序就知道是怎麽回事了,老樣子,放源碼: 攔截器的源碼在這裏

基於JavaConfig配置的攔截器使用