成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java中的過濾器和攔截器有什么區別么?

開發 前端
我們自定義一個獲取并返回某個靜態資源的內容以及整個請求所花費的時間攔截器,一般這個還是比較有用的,而且還可以加一個請求訪問的,然后來處理方法執行時間的。

今天我們不談框架,我們來說說這個 Java 基礎中的過濾器和攔截器,為什么要談呢?其實就有粉絲會問了不起,這個過濾器和攔截器他們有什么區別呢?為什么面試官在面試的時候經常會問到這個過濾器和攔截器的區別,以及他們分別對應的應用場景呢?

今天了不起就來說說這個過濾器和攔截器。

過濾器

過濾器 Filter

什么是過濾器

過濾器是 Servlet 的高級特性之一,是實現 Filter 接口的 Java 類。其基本功能就是對 servlet 的調用進行干預,在 Servlet 請求和響應的過程中增加一些特定的功能。可以使用過濾器實現的功能有:統一編碼,URL級別的權限訪問控制,過濾敏感詞匯,壓縮請求信息.

我們來通過代碼來看 Filter 的執行過程

public interface Filter {
    //用于執行過濾器的初始化工作,web容器會在web項目啟動時自動調用該方法
    default void init(FilterConfig filterConfig) throws ServletException {
    }
 
    //當請求和響應被過濾器攔截后,都會交給doFilter來處理:其中兩個參數分別是被攔截request和response對象,可以使用chain的doFliter方法來放行
    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
    //用于釋放關閉Filter對象打開的資源,在web項目關閉時,由web容器自動調用該方法
    default void destroy() {
    }
}

在 Filter 中我們可以看到有三個方法,分別是

  • init
  • doFilter
  • destroy

至于每個方法的作用,了不起已經把他們的功能寫在了注釋上面,他們實際上就是三個步驟:

1.初始化

2.處理請求和相應過濾,完成操作

3.最后釋放資源

而實現一個自定義 Filter 也是比較簡單的,我們來實現一個簡單的自定義的 Filter。

@Component
@Slf4j
public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("初始化過濾器:" + filterConfig.getFilterName());
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        // 對請求進行過濾操作處理
        log.info("MyFilter 開始對請求進去過濾操作!");
        String requestURI = httpRequest.getRequestURI();
        log.info("請求地址:" + requestURI);

        // 繼續執行下一個 Filter,如果沒有其他 Filter 的話就執行 Controller 層代碼
        long startTime = System.currentTimeMillis();
        chain.doFilter(request, response);

        // 執行完用戶請求后,回到這里對 response 響應內容做一些處理
        long endTime = System.currentTimeMillis();
        log.info("請求處理完畢,所花費時間為:" + (endTime - startTime) + "ms");
    }

    @Override
    public void destroy() {
        log.info("銷毀過濾器 MyFilter");
    }

}

至于 Filter 的配置的話,了不起都不用解釋,現在幾乎沒有再去配置 xml 的方式了,都是配置類或者注解的方式。

注解方式:

@WebFilter(filterName = "myFilter",urlPatterns = {"/*"})

配置類方式:

@Configuration
public class MyFilterConfig {
 
    @Bean
    public FilterRegistrationBean myFilter(){
        FilterRegistrationBean fb = new FilterRegistrationBean();
        //設置filter啟動順序
        fb.setOrder(1);
        fb.setFilter(new MyFilter());
        fb.addInitParameter("phone","183****5510");
        //設置攔截請求規則,這里攔截所有請求
        fb.addUrlPatterns("/*");
        return fb;
    }
}

我們看完了這個過濾器,接下來就得看看這個攔截器了。

攔截器

攔截器 Interceptor

什么是攔截器

Spring MVC 中的攔截器Interceptor類似于 ServLet 中的過濾器Filter,它主要用于攔截用戶請求并作出相應的處理。例如通過攔截器可以進行權限驗證、記錄請求信息的日志、判斷用戶是否登錄等。

老規矩,直接看源代碼

public interface HandlerInterceptor {
    //預處理方法,本方法在控制器方法(MyController的方法)之前執        行,用戶的請求最先到達此方法,在這個方法中可以獲取請求的信息,驗證請求是否符合要求。以驗證用戶是否登錄,驗證用戶是否有權限訪問某個鏈接地址(url)。如果返回true則放行,返回false則攔截
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }
    //后處理方法。在controller中的方法之后執行的。能夠獲取到處理器方法的返回值 mv,可以修改mv中的數據和視圖。可以影響到最后的執行結果。主要是對原來的執行結果做二次修正
    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }
    //最后執行的方法,在頁面渲染之后執行。在請求處理完成后執行的,框架中規定是當你的視圖處理完成后,對視圖進行了forword。就任務請求處理完成。
    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}

其實也是三個步驟:

1.預處理

2.后處理

3.最后執行

至于每一步的含義和內容,了不起同樣的再注釋中表明了。

同樣的,自定義實現一個攔截器也很簡單:

public class MyInterceptor implements HandlerInterceptor {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyInterceptor.class);

    private static final ThreadLocal<Long> START_THREAD_LOCAL = new ThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        String uri = request.getRequestURI();
        LOGGER.info(uri + " preHandle");
        Long startTime = System.currentTimeMillis();    //獲取開始時間
        START_THREAD_LOCAL.set(startTime);  //線程綁定變量(該數據只有當前請求的線程可見)
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        String uri = request.getRequestURI();
        LOGGER.info(uri + " postHandle");
        Long startTime = START_THREAD_LOCAL.get();//得到線程綁定的局部變量(開始時間)
        Long endTime = System.currentTimeMillis();  //2、結束時間
        Long time = endTime - startTime;
        LOGGER.info("http request all time: " + time + "ms");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                Exception ex) throws Exception {
        String uri = request.getRequestURI();
        LOGGER.info(uri + " afterCompletion");
        if (START_THREAD_LOCAL != null) {
            START_THREAD_LOCAL.remove();    // 移除ThreadLocal中的局部變量
        }
    }
}

我們自定義一個獲取并返回某個靜態資源的內容以及整個請求所花費的時間攔截器,一般這個還是比較有用的,而且還可以加一個請求訪問的,然后來處理方法執行時間的。

配置攔截器其實在項目中是非常的常見。

@Configuration
public class MyInterceptorConfig implements WebMvcConfigurer {
 
    /**
     * 配置攔截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(myInterceptor())
                .addPathPatterns("/api/v1/**")//需要攔截的請求
                .addPathPatterns("/api/v1/**")//需要攔截的請求
                .excludePathPatterns("/api/debug/**")//不攔截的請求
                .excludePathPatterns("api/page/getName");//不攔截的請求
    }
 
    /**
     * 注入攔截器到spring容器
     * @return
     */
    @Bean
    public MyInterceptor myInterceptor(){
        return new MyInterceptor();
    }
}

我們看完了過濾器和攔截器的實現,接下來就得來看看這個過濾器和攔截器之間的區別了。

1.依賴點不同

  • 過濾器依賴與servlet容器,而攔截器不依賴與servlet容器
  • 過濾器屬于Servlet,而攔截器屬于springmvc

2.實現原理不同

  • 過濾器是基于函數回調,而攔截器是基于java的反射機制的

3.作用域不同

  • 過濾器則可以對幾乎所有的請求起作用,而攔截器只能對action請求起作用

4.生命周期不同

  • 在action的生命周期中,攔截器可以多次被調用,而過濾器只能在容器初始化時被調用一次

這是區別,其實二者的相同點也是有的,比如,攔截器和過濾器實際上都是 Spring 中 AOP 的體現,都能實現一些權限和日志方面的功能。

你知道他們是什么區別了么?

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2023-02-20 07:19:14

2022-01-13 10:04:21

攔截器Interceptor過濾器

2023-09-15 11:26:16

2020-09-14 12:46:25

過濾器攔截器Filter

2024-01-17 08:56:31

2024-01-08 08:33:53

AOPSpring攔截器

2020-06-04 07:45:07

過濾器和攔截器

2016-12-07 09:56:13

JavaFilter過濾器

2025-05-12 18:49:52

2024-01-05 09:04:35

隆過濾器數據結構哈希函數

2009-07-08 15:30:56

Servlet過濾器

2022-08-31 08:33:54

Bash操作系統Linux

2024-11-04 08:45:48

布隆過濾器元數據指紋值

2021-09-03 06:33:24

布隆過濾器高并發

2020-07-20 09:18:43

存儲數據技術

2020-08-02 23:20:36

JavaScriptmap()forEach()

2025-04-27 08:15:00

FlinkSavepointCheckpoint

2021-07-05 15:22:03

Servlet過濾器客戶端

2021-03-27 10:56:17

promisethenfinally

2022-09-02 09:02:44

TypeInterface
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 男女视频免费 | av国产精品| 亚洲成人av | 日韩av在线不卡 | 久久九精品 | 精品国产乱码久久久久久88av | 一级免费毛片 | 综合自拍 | 国产精品美女久久久久久久久久久 | 欧美一区二区三区小说 | 一区二区国产精品 | 四虎成人精品永久免费av九九 | 国产电影一区二区 | 亚洲精品日韩视频 | 黑人精品欧美一区二区蜜桃 | 欧美精品一区二区三区蜜桃视频 | 国产精品视频专区 | 国产日韩欧美在线 | 91精品福利 | 国产综合在线视频 | 亚洲视频一区在线观看 | 国产精品观看 | 亚洲 欧美 另类 综合 偷拍 | 特黄级国产片 | 在线欧美视频 | 中文一区二区视频 | 中文字幕第5页 | 亚洲美女在线视频 | 国产一区二区影院 | 欧美激情va永久在线播放 | 欧美 日韩 国产 成人 | 一区二区三区国产 | 国产高清在线 | av中文字幕在线观看 | 欧美一级免费看 | 日本爱爱| 亚洲成人在线网 | wwww.xxxx免费 | 拍拍无遮挡人做人爱视频免费观看 | 亚洲成人免费 | 欧美一二三 |