Java Web學習(九)Java攔截器


 文章更新時間:2020/04/07

一、引言

  既然要用攔截器,首先先得簡單了解一下什么是攔截器:

  概念:java里的攔截器是動態攔截Action調用的對象,它提供了一種機制可以使開發者在一個Action執行的前后執行一段代碼,也可以在一個Action執行前阻止其執行,同時也提供了一種可以提取Action中可重用部分代碼的方式。

  作用域:動態攔截Action調用的對象(也就是我們的controller層)

  我們日常開發中,經常會遇到這個場景:在訪問系統功能前,需要用戶登錄,不登陸的話無法使用我們的系統,那么如果在每個方法前都加上登錄代碼...【emmm....我想應該不會有人這么干吧...】,常見的可以使用以下幾種方式:

  • 使用AOP切面功能來實現
  • 使用Spring的攔截器相關接口來自定義攔截器
    • 實現WebMvcConfigurer接口,重寫addCorsMappings()方法和addInterceptors()方法【配置攔截器】
    • 實現HandlerInterceptor接口或者繼承HandlerInterceptorAdapter,重寫preHandle()方法【自定義攔截器】

  下面我們就一起來看下一下怎么實現吧~

二、代碼實現

AOP切面方式

   切面方式配置的話,得配置到包路徑下或者每個具體方法都要配置,個人不是很喜歡用切面的方式來配置攔截器,用來記錄日志或者其他功能可以使用aop,這篇文章就不詳細講解了,只簡單說明一下以切面方式實現時的大致模型,我們着重看下以另一種方式來實現攔截器的功能。

實現WebMvcConfigurer接口的方式

  WebMvcConfigurer配置類其實是Spring內部的一種配置方式,采用JavaBean的形式來代替傳統的xml配置文件形式進行針對框架個性化定制,可以自定義一些HandlerInterceptorViewResolverMessageConverter

  基於java-based方式的spring mvc配置,需要創建一個配置類並實現WebMvcConfigurer 接口。在Spring Boot 1.5版本都是靠重寫WebMvcConfigurerAdapter的方法來添加自定義攔截器,消息轉換器等。SpringBoot 2.0 后,該類被標記為@Deprecated(棄用)。官方推薦直接實現WebMvcConfigurer或者直接繼承WebMvcConfigurationSupport。

  簡單介紹一下WebMvcConfigurer中比較重要的幾個方法:

  • addInterceptors添加攔截器
  • addCorsMappings跨域
  • addViewControllers頁面跳轉(不用像現在我們要寫一個Controller進行映射就可實現跳轉)
  • addResourceHandlers靜態資源(自定義靜態資源映射目錄)
  • configureDefaultServletHandling默認靜態資源處理器
  • configureViewResolvers視圖解析器(配置請求視圖映射,配置了以后我們返回一個頁面路徑的字符串時,解析器會幫我們拼裝前綴和后綴等信息)
  • configureMessageConverters信息轉換器(比如我們入參的信息直接轉換成json或者轉換成對應的bean類就具體在這里配置)

  這里我們主要應用的是前兩個方法,添加攔截器和跨域配置,下面來看下具體實現:

 

 攔截器配置源碼:

/**
 * 攔截器的屬性配置
 *
 * @Author 有夢想的肥宅
 */
@Configuration//標識這是一個配置類
public class InterceptorConfiguration implements WebMvcConfigurer {

    /**
     * 重寫addCorsMappings()解決跨域問題
     * 配置:允許http請求進行跨域訪問
     *
     * @param registry
     * @Author 有夢想的肥宅
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")//指哪些接口URL需要增加跨域設置
                .allowedOrigins("*")//指的是前端哪些域名被允許跨域
                .allowCredentials(true)//需要帶cookie等憑證時,設置為true,就會把cookie的相關信息帶上
                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")//指的是允許哪些方法
                .maxAge(3600);//cookie的失效時間,單位為秒(s),若設置為-1,則關閉瀏覽器就失效
    }

    /**
     * 重寫addInterceptors()實現攔截器
     * 配置:要攔截的路徑以及不攔截的路徑
     *
     * @param registry
     * @Author 有夢想的肥宅
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注冊Interceptor攔截器(Interceptor這個類是我們自己寫的攔截器類)
        InterceptorRegistration registration = registry.addInterceptor(new Interceptor());
        //addPathPatterns()方法添加需要攔截的路徑
        registration.addPathPatterns("/**");                      //所有路徑都被攔截
        //excludePathPatterns()方法添加不攔截的路徑
        registration.excludePathPatterns(                         //添加不攔截路徑
                "/demo/loginPage",            //登錄頁面的地址【不攔截】
                "/**/*.html",            //html靜態資源
                "/**/*.js",              //js靜態資源
                "/**/*.css"              //css靜態資源
        );
    }
}

自定義攔截器源碼:

/**
 * 攔截器
 * @Author 有夢想的肥宅
 */
public class Interceptor implements HandlerInterceptor {
    /**
     * 在請求處理之前進行調用(Controller方法調用之前)
     * @Author 有夢想的肥宅
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        System.out.println("執行了Interceptor的preHandle方法");
        try {
            //統一攔截(查詢當前session是否存在UserInfoVO用戶信息)(這里UserInfoVO會在每次登陸成功后,寫入session)
            UserInfoVO user = (UserInfoVO) request.getSession().getAttribute("UserInfoVO");
            if (user != null) {
                return true;
            }
            //這里設置攔截以后重定向的頁面,一般設置為登陸頁面地址
            response.sendRedirect(request.getContextPath() + "/demo/loginPage");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;//如果設置為false時,被請求時,攔截器執行到此處將不會繼續操作
        //如果設置為true時,請求將會繼續執行后面的操作
    }
}

小結:從上面的代碼可以看出,要實現攔截器一般需要以下幾個步驟:

  • 1、寫一個實現了WebMvcConfigurer接口的配置類
  • 2、重寫其中的addCorsMappings()方法【配置跨域信息】和addInterceptors()方法【配置攔截器信息,如攔截路徑和開放路徑等】
  • 3、寫一個實現HandlerInterceptor接口的自定義攔截器
  • 4、重寫其中的preHandle()方法,方法內容為攔截到請求后的處理

 

 

參考文章:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM