springBoot(6)---過濾器,監聽器,攔截器


過濾器,監聽器,攔截器

 

一、理解它們

    看里十幾篇博客,總算有點小明白,總的來講,兩張圖可以讓我看明白點。

   通過兩幅圖我們可以理解攔截器和過濾器的特點

1、過濾器

  過濾器是在請求進入tomcat容器后,但請求進入servlet之前進行預處理的。請求結束返回也是,是在servlet處理完后,返回給前端之前。

      理解上面這句話我們就可以知道,進入servlet之前,主要是兩個參數:ServletRequestServletResponse  那我們得到這兩個測試可以干哪些事呢?

     我們可以通過ServletRequest得到HttpServletRequest,此時你就可以對請求或響應(Request、Response)那就可以對對web服務器管理的所有web資源例如Jsp, Servlet, 靜態圖片文件或靜態 html 文件等進行攔截,從而實現一些特殊的功能。例如實現URL級別的權限訪問控制、過濾敏感詞匯、壓縮響應信息、字符集統一等一些高級功能。它主要用於對用戶請求進行預處理,也可以對HttpServletResponse進行后處理。使用Filter的完整流程:Filter對用戶請求進行預處理,接着將請求交給Servlet進行處理並生成響應,最后Filter再對服務器響應進行后處理。。它是隨你的web應用啟動而啟動的,只初始化一次,以后就可以攔截相關請求,只有當你的web應用停止或重新部署的時候才銷毀。(每次熱部署后,都會銷毀)。

2、攔截器

從上圖我們可以看出過濾器只在servlet前后起作用,所以它既不能捕獲異常,獲得bean對象等,這些是只能是進入servlet里面的攔截器能過做到。攔截器中用於在某個方法或字段被訪問之前,進行攔截然后,在之前或之后加入某些操作。比如日志,安全等。一般攔截器方法都是通過動態代理的方式實現。可以通過它來進行權限驗證,或者判斷用戶是否登陸,或者是像12306 判斷當前時間是否是購票時間。

對比一下其實我們可以發現,過濾器能做的事攔截器都能做,二攔截器做的事過濾器不一定做的了。

3、監聽器

listener是servlet規范中定義的一種特殊類。用於監聽servletContextHttpSessionservletRequest等域對象的創建和銷毀事件。監聽域對象的屬性發生修改的事件。用於在事件發生前、發生后做一些必要的處理。其主要可用於以下方面:1、統計在線人數和在線用戶2、系統啟動時加載初始化信息3、統計網站訪問量4、記錄用戶訪問路徑。

常用的監聽器 servletContextListenerhttpSessionListenerservletRequestListener)

 

二、如何創建他們

1、過濾器

自定義Filter 使用Servlet3.0的注解進行配置第三步的@WebFilter就是3.0的注解

       1)啟動類里面增加 @ServletComponentScan,進行掃描

       2)新建一個Filter類,implements Filter,並實現對應的接口

        3) @WebFilter 標記一個類為filter,被spring進行掃描

        urlPatterns:攔截規則,支持正則

        4)控制chain.doFilter的方法的調用,來實現是否通過放行不放行,web應用resp.sendRedirect("/index.html");場景:權限控制、用戶登錄(非前端后端分離場景)等

  application類

@SpringBootApplication
@ServletComponentScan public class SpringbootstudyApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootstudyApplication.class, args);
    }
}

  LoginFilter過濾器

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

//過濾器攔截路徑
@WebFilter(urlPatterns = "/api/*", filterName = "loginFilter")
public class LoginFilter  implements Filter{
          
     /**
      * 容器加載的時候調用
      */
      @Override
      public void init(FilterConfig filterConfig) throws ServletException {
          System.out.println("攔截器進入========攔截器進入========");
      }
      
      /**
       * 請求被攔截的時候進行調用
       */
      @Override
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
          System.out.println("攔截中========攔截中========");

          HttpServletRequest hrequest = (HttpServletRequest)servletRequest;
          HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) servletResponse);
          if(hrequest.getRequestURI().indexOf("/index") != -1 ||
                  hrequest.getRequestURI().indexOf("/asd") != -1 ||
                  hrequest.getRequestURI().indexOf("/online") != -1 ||
                  hrequest.getRequestURI().indexOf("/login") != -1
                  ) {
              filterChain.doFilter(servletRequest, servletResponse);
          }else {
              wrapper.sendRedirect("/login");
          }
          
      }

      /**
       * 容器被銷毀的時候被調用
       */
      @Override
      public void destroy() {
          System.out.println("攔截器銷毀========攔截器銷毀========");
      }

}

1、官網地址:https://docs.spring.io/spring-boot/docs/2.1.0.BUILD-SNAPSHOT/reference/htmlsingle/#boot-features-embedded-container-servlets-filters-listeners

 

二、監聽器

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;

@WebListener public class RequestListener implements ServletRequestListener {

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        // TODO Auto-generated method stub
        System.out.println("======銷毀監聽器========");
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("======進入監聽器========");
        
    }

 

三、攔截器

CustomWebMvcConfigurer主攔截器需要:

    1:添加@Configuration注解

    2:實現WebMvcConfigurer接口

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

//主攔截器,根據攔截不同路徑跳轉不同自定義攔截器 (實現WebMvcConfigurer方法)
@Configuration
public class CustomWebMvcConfigurer implements WebMvcConfigurer  {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/api1/*/**");
        registry.addInterceptor(new TwoIntercepter()).addPathPatterns("/api2/*/**");
        
        //.excludePathPatterns("/api2/xxx/**"); //攔截全部 /*/*/**
        
        WebMvcConfigurer.super.addInterceptors(registry);
    }

}

LoginIntercepter子攔截器

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class LoginIntercepter implements HandlerInterceptor{

    /**
     * 進入controller方法之前
     */
    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        System.out.println("LoginIntercepter------->preHandle");

//        String token = request.getParameter("access_token");
//        
//        response.getWriter().print("fail");
        
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    /**
     * 調用完controller之后,視圖渲染之前
     */
    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        
        System.out.println("LoginIntercepter------->postHandle");
        
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    /**
     * 整個完成之后,通常用於資源清理
     */
    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("LoginIntercepter------->afterCompletion");
        
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
    
    
}

TwoIntercepter同上

 

github地址:源碼

最后總解一下他們:

過濾器:用於屬性甄別,對象收集(不可改變過濾對象的屬性和行為)

監聽器:用於對象監聽,行為記錄(不可改變監聽對象的屬性和行為)

攔截器:用於對象攔截,行為干預(可以改變攔截對象的屬性和行為)

 

參考:

1.springboot配置監聽器、過濾器和攔截器

2.請教一下關於過濾器,攔截器,監聽器具體應用上的區別?

3.springboot過濾器和攔截器的實現和區別

 

 

想太多,做太少,中間的落差就是煩惱。想沒有煩惱,要么別想,要么多做。上尉【8】

 


免責聲明!

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



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