過濾器Filter介紹和使用

一撒强、Filter介紹

過濾器概念

  • 客戶端與服務(wù)器資源文件之間的一道過濾網(wǎng)笙什;
  • 管理Web服務(wù)器的所有資源琐凭,例如對JSP、Servlet胚吁、靜態(tài)圖片文件或靜態(tài)HTML文件等進(jìn)行攔截愁憔;
  • 可以過濾幾乎所有的請求,完成一些特殊的功能蕉毯;
  • Filter依賴于Servlet容器,屬于Servlet規(guī)范的一部分进肯;
  • Filter的執(zhí)行由Servlet容器回調(diào)完成棉磨;
  • Filter的生命周期由Servlet容器管理。

過濾器使用場景

完成通用的操作:登陸驗證环形、URL級別的權(quán)限訪問控制抬吟、壓縮響應(yīng)信息统抬、統(tǒng)一編碼處理、過濾敏感字符等等钙畔。

過濾器實現(xiàn)步驟

  • 定義一個類金麸,實現(xiàn)javax.servlet.Filter接口;
  • 復(fù)寫方法揍魂,尤其是doFilter方法愉烙,必須實現(xiàn)解取;
  • 配置過濾器信息返顺。
    • web.xml
    • @WebFilter注解
    • @Configuration配置類

過濾器生命周期

Filter的生命周期由Servlet容器管理:

  • init:在服務(wù)器啟動后遂鹊,會創(chuàng)建Filter對象,然后調(diào)用init方法慧邮。只執(zhí)行一次。用于加載資源耻矮。
  • doFilter:每一次請求被攔截資源時忆谓,會執(zhí)行。執(zhí)行多次哨免。
  • destroy:在服務(wù)器關(guān)閉后昙沦,F(xiàn)ilter對象被銷毀盾饮。如果服務(wù)器是正常關(guān)閉,則會執(zhí)行destroy方法芍碧。只執(zhí)行一次号俐。用于釋放資源吏饿。

過濾器攔截路徑配置

  • 具體的資源路徑: /hello.jsp 只訪問hello.jsp資源時,過濾器才會被執(zhí)行
  • 攔截目錄: /hello/* 訪問/hello下的所有資源時贞远,過濾器才會被執(zhí)行
  • 后綴名攔截: *.jsp 訪問所有后綴名為jsp資源時笨忌,過濾器才會被執(zhí)行
  • 攔截所有資源: /* 訪問所有資源時,過濾器才會被執(zhí)行

過濾器攔截請求調(diào)度方式配置

  • 請求調(diào)度方式
    • REQUEST:默認(rèn)值袱结。瀏覽器直接請求資源
    • FORWARD:轉(zhuǎn)發(fā)訪問資源
    • NCLUDE:包含訪問資源
    • ERROR:錯誤跳轉(zhuǎn)資源
    • ASYNC:異步訪問資源
  • web.xml配置:<filter-mapping>中的<dispatcher>標(biāo)簽
  • @WebFilter注解配置:dispatcherTypes屬性
  • @Configuration配置類:FilterRegistrationBean對象的dispatcherTypes屬性

過濾器鏈(多個過濾器)調(diào)用的先后順序

  • web.xml: <filter-mapping>定義在上邊的垢夹,先執(zhí)行
  • @WebFilter注解:按照類名字符串比較規(guī)則比較维费,值小的先執(zhí)行(注意不是配置的filter的名字)
    • 如: AFilter 和 BFilter,AFilter就先執(zhí)行了而晒。
    • 如: AFilter17 和 AFilter6欣硼,AFilter17就先執(zhí)行了。
  • @Order注解:值小的先執(zhí)行
  • Configuration配置類:FilterRegistrationBean對象的order屬性:值小的先執(zhí)行
  • @WebFilter指定的過濾器優(yōu)先級都高于FilterRegistrationBean配置的過濾器

過濾器鏈(多個過濾器)執(zhí)行的先后順序

  • FilterChain的執(zhí)行順序遵循先進(jìn)后出原則
  • 以doFilter方法中調(diào)用filterChain.doFilter(servletRequest,servletResponse)的位置為準(zhǔn)豹障,這里放行到下一個過濾器焦匈;
  • filterChain.doFilter位置之前的代碼先執(zhí)行缓熟,然后再放行;
  • filterChain.doFilter位置之后的代碼是響應(yīng)回來后再執(zhí)行垦写;
  • Request請求被所有的Filter處理之后,返回的順序是從最后一個開始返回,直到返回給客戶端

二彰触、Filter使用

Java Web使用Filter

基于實現(xiàn)Filter + web.xml配置

創(chuàng)建一個類况毅,實現(xiàn)javax.servlet.Filter接口,尤其是doFilter方法么鹤;

package com.liutit.filter;

import javax.servlet.*;
import java.io.IOException;

public class DemoFilter  implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 客戶端發(fā)送請求經(jīng)過過濾器蒸甜,
        // 這里一般處理請求對象Request
        System.out.println("filter in....");
        
        // 放行
        filterChain.doFilter(servletRequest,servletResponse);
        
        // 服務(wù)器響應(yīng)請求后毡们,經(jīng)過此處,然后再到客戶端,
        // 這里一般處理響應(yīng)對象Response
        System.out.println("filter out....");
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

在web.xml中配置過濾器信息红氯;

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
   <filter>
      <filter-name>demo</filter-name>
      <filter-class>com.liutit.filter.DemoFilter</filter-class>
   </filter>
   <!-- filter-mapping標(biāo)簽定義的位置決定多個過濾器調(diào)用的順序痢甘,由上而下依次調(diào)用, 與filter標(biāo)簽的定義位置無關(guān)-->
   <filter-mapping>
      <filter-name>demo</filter-name>
      <!-- 攔截路徑 -->
      <url-pattern>/*</url-pattern>
      <!-- 攔截方式 -->
      <dispatcher>REQUEST</dispatcher>
   </filter-mapping>
</web-app>

基于實現(xiàn)Filter + @WebFilter注解

創(chuàng)建一個類者铜,實現(xiàn)javax.servlet.Filter接口放椰,尤其是doFilter方法砾医,并在類上添加@WebFilter注解;

package com.liutit.filter;

import javax.servlet.*;
import java.io.IOException;

@WebFilter("/*")
public class DemoFilter  implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 客戶端發(fā)送請求經(jīng)過過濾器压恒,
        // 這里一般處理請求對象Request
        System.out.println("filter in....");
        
        // 放行
        filterChain.doFilter(servletRequest,servletResponse);
        
        // 服務(wù)器響應(yīng)請求后探赫,經(jīng)過此處撬呢,然后再到客戶端,
        // 這里一般處理響應(yīng)對象Response
        System.out.println("filter out....");
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

Spring Boot使用Filter

pom.xml導(dǎo)入pring-boot-starter-web包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

基于實現(xiàn)Filter + 配置Configuration類

package com.liutit.filter;

import javax.servlet.*;
import java.io.IOException;

public class DemoFilter  implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 客戶端發(fā)送請求經(jīng)過過濾器,
        // 這里一般處理請求對象Request
        System.out.println("filter in....");
        
        // 放行
        filterChain.doFilter(servletRequest,servletResponse);
        
        // 服務(wù)器響應(yīng)請求后潭千,經(jīng)過此處借尿,然后再到客戶端,
        // 這里一般處理響應(yīng)對象Response
        System.out.println("filter out....");
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

Configuration類

package com.liutit.config;

import com.liutit.filter.DemoFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.DispatcherType;

@Configuration
public class FilterConfiguration {

    @Bean
    public FilterRegistrationBean registrationFilter() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        // 設(shè)置過濾器
        filterRegistration.setFilter(new DemoFilter());
        // 指定url策略
        filterRegistration.addUrlPatterns("/*");
        // 指定過濾請求調(diào)度方式,默認(rèn)REQUEST
        filterRegistration.setDispatcherTypes(DispatcherType.REQUEST);
        // 設(shè)置過濾器名稱
        filterRegistration.setName("demoFilter");
        // 過濾器順序:數(shù)字越小茂契,越先執(zhí)行
        filterRegistration.setOrder(1);
        return filterRegistration;
    }
}


基于實現(xiàn)Filter + @WebFilter注解 + @ServletComponentScan注解

package com.liutit.filter;

import javax.servlet.*;
import java.io.IOException;

@Order(1)
@WebFilter("/*")
public class DemoFilter  implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 客戶端發(fā)送請求經(jīng)過過濾器掉冶,
        // 這里一般處理請求對象Request
        System.out.println("filter in....");
        
        // 放行
        filterChain.doFilter(servletRequest,servletResponse);
        
        // 服務(wù)器響應(yīng)請求后,經(jīng)過此處战秋,然后再到客戶端讨韭,
        // 這里一般處理響應(yīng)對象Response
        System.out.println("filter out....");
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

啟動類上添加@ServletCoponentScan注解

在啟動類上使用@ServletComponentScan注解后,
Servlet狰闪、Filter蹬铺、Listener可以直接通過@WebServlet甜攀、@WebFilter、@WebListener注解自動注冊恒序。

package com.liutit;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@ServletComponentScan
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載歧胁,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者厉碟。
  • 序言:七十年代末箍鼓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子何暮,更是在濱河造成了極大的恐慌铐殃,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡俯树,警方通過查閱死者的電腦和手機贰盗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門舵盈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秽晚,“玉大人赴蝇,你說我怎么就攤上這事句伶。” “怎么了楚堤?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵身冬,是天一觀的道長酥筝。 經(jīng)常有香客問我樱哼,道長剿配,這世上最難降的妖魔是什么呼胚? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮沪编,結(jié)果婚禮上蚁廓,老公的妹妹穿的比我還像新娘。我一直安慰自己相嵌,他們只是感情好腿时,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著饭宾,像睡著了一般批糟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上看铆,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天徽鼎,我揣著相機與錄音,去河邊找鬼弹惦。 笑死否淤,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的肤频。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼宵荒,長吁一口氣:“原來是場噩夢啊……” “哼汁雷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起报咳,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤侠讯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后暑刃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體厢漩,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年岩臣,在試婚紗的時候發(fā)現(xiàn)自己被綠了溜嗜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡架谎,死狀恐怖炸宵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情谷扣,我是刑警寧澤土全,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響裹匙,放射性物質(zhì)發(fā)生泄漏瑞凑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一概页、第九天 我趴在偏房一處隱蔽的房頂上張望籽御。 院中可真熱鬧,春花似錦绰沥、人聲如沸篱蝇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至麸塞,卻和暖如春秃臣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背哪工。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工奥此, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人雁比。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓稚虎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親偎捎。 傳聞我的和親對象是個殘疾皇子蠢终,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容