springboot2.x | 過濾器(Filter)的使用

servlet簡介

過濾器,依靠servlet技術(shù)。
Java Servlet 是運(yùn)行在 Web 服務(wù)器或應(yīng)用服務(wù)器上的程序馍迄,它是作為來自 Web 瀏覽器或其他 HTTP 客戶端的請求和 HTTP 服務(wù)器上的數(shù)據(jù)庫或應(yīng)用程序之間的中間層兴泥。
servlet文檔:
https://www.runoob.com/servlet/servlet-intro.html

servlet 和tomcat 是什么關(guān)系主卫?

過濾器簡介

過濾器Filter,是Servlet的的一個實用技術(shù)了鹃愤〈亟粒可通過過濾器,對請求進(jìn)行攔截软吐,比如讀取session判斷用戶是否登錄瘩将、判斷訪問的請求URL是否有訪問權(quán)限(黑白名單)等。主要還是可對請求進(jìn)行預(yù)處理凹耙。

1.過濾器和攔截器觸發(fā)時機(jī)不一樣姿现,過濾器是在請求進(jìn)入容器后,但請求進(jìn)入servlet之前進(jìn)行預(yù)處理的使兔。請求結(jié)束返回也是建钥,是在servlet處理完后,返回給前端之前虐沥。


flq.png

2.攔截器可以獲取IOC容器中的各個bean熊经,而過濾器就不行,因為攔截器是spring提供并管理的欲险,spring的功能可以被攔截器使用镐依,在攔截器里注入一個service,可以調(diào)用業(yè)務(wù)邏輯天试。而過濾器是JavaEE標(biāo)準(zhǔn)槐壳,只需依賴servlet api ,不需要依賴spring喜每。


gg.png

1 通過@WebFilter來定義filter,

自定義 AllUrlFilter

@Slf4j
@WebFilter(filterName = "allurlfilter", urlPatterns = {"/*"})
public class AllUrlFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        log.info("all url filter -->" + filterConfig.toString());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("all url filter do filter");

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        System.out.println(request.getHeader("token"));
        //往下文傳遞
        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        log.info("all url filter do destroy");
    }
}

在springboot 啟動器類上加上注解 @ServletComponentScan

@SpringBootApplication
@ServletComponentScan
public class StudySpringbootApplication {
    public static void main(String[] args) {
        SpringApplication.run(StudySpringbootApplication.class, args);
    }
}

總結(jié):
Filter使用白名單過濾Url的方式务唐,配置需要攔截的Url,如果想設(shè)置不過濾某些Url需要在doFilter方法中指定带兜。
通過@WebFilter的方式定義Filter枫笛,默認(rèn)使用Filter的類名設(shè)置優(yōu)先級。使用FilterRegistrationBean可以指定優(yōu)先級

2 filter 中的異常處理

2.1 制造錯誤

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        log.info("all url filter do filter");

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        System.out.println(request.getHeader("token"));

        try {
            int i = 0 / 0;
        } catch (Exception e) {
            //錯誤封裝在 request 中
            request.setAttribute("errormsg", e.getMessage());
            //
            request.getRequestDispatcher("/500").forward(request, response);
        }

        filterChain.doFilter(request, response);
    }

盡量使用request.getRequestDispatcher("/500").forward(req, resp);此方式只會在服務(wù)器內(nèi)部轉(zhuǎn)發(fā)客戶端地址不會發(fā)生任何改變刚照;如果使用response.sendRedirect("/500");請求轉(zhuǎn)發(fā)刑巧,客戶端地址會發(fā)生改變

2.2 添加/500 url

  @GetMapping("/500")
    public Response excep401(HttpServletRequest request) throws CustomException {

        System.out.println(request.getAttribute("errormsg"));

        throw new CustomException();
    }

方法2 : 通過FilterRegistrationBean來定義 多個filter

所有的filter 去掉 @WebFilter

3.1 新建HelloFilter

@Slf4j
//@WebFilter(filterName = "helloFilter" , urlPatterns = {"/hello/*"})
public class HelloFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        log.info("hello filter --> " + filterConfig.toString());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        log.info("hello do filter");

        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

        log.info("hello do destroy");
    }
}

3.2 新建UserFilter

@Slf4j
//@WebFilter(filterName = "userFilter", urlPatterns = {"/user/*"})
public class UserFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        log.info("user filter --> " + filterConfig.toString());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        log.info("user do filter");

        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

        log.info("user do destroy");

    }
}

3.3 新建 FilterConfig 配置

@Configuration
public class FilterConfig {

    @Bean
    public AllUrlFilter allUrlFilter(){
        return new AllUrlFilter();
    }

    @Bean
    public UserFilter userFilter(){
        return new UserFilter();
    }

    @Bean
    public HelloFilter helloFilter(){
        return new HelloFilter();
    }

    @Bean
    public FilterRegistrationBean filterRegistrationBean(AllUrlFilter allUrlFilter){
        FilterRegistrationBean registration = new FilterRegistrationBean();

        registration.setFilter(allUrlFilter);
        registration.setName("allUrlFilter");
        List<String> urlList  =  new ArrayList<>();
        urlList.add("/*");
        registration.setUrlPatterns(urlList);
        registration.setOrder(1);

        return registration;
    }


    @Bean
    public FilterRegistrationBean filterRegistrationBea2(HelloFilter helloFilter){
        FilterRegistrationBean registration = new FilterRegistrationBean();

        registration.setFilter(helloFilter);
        registration.setName("helloFilter");
        List<String> urlList  =  new ArrayList<>();
        urlList.add("/hello/*");
        registration.setUrlPatterns(urlList);
        registration.setOrder(2);

        return registration;
    }


    @Bean
    public FilterRegistrationBean filterRegistrationBea3(UserFilter userFilter){
        FilterRegistrationBean registration = new FilterRegistrationBean();

        registration.setFilter(userFilter);
        registration.setName("userFilter");
        List<String> urlList  =  new ArrayList<>();
        urlList.add("/user/*");
        registration.setUrlPatterns(urlList);
        registration.setOrder(3);

        return registration;
    }

}

SpringBoot中使用Filter和Interceptor
https://juejin.cn/post/6844903869927931918
Spring Interceptor vs Filter
https://juejin.cn/post/6844903828970553358
SpringBoot圖文教程6—SpringBoot中過濾器的使用
https://juejin.cn/post/6844904072173060109

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市无畔,隨后出現(xiàn)的幾起案子啊楚,更是在濱河造成了極大的恐慌,老刑警劉巖浑彰,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恭理,死亡現(xiàn)場離奇詭異,居然都是意外死亡郭变,警方通過查閱死者的電腦和手機(jī)颜价,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門薄风,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人拍嵌,你說我怎么就攤上這事遭赂。” “怎么了横辆?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵撇他,是天一觀的道長。 經(jīng)常有香客問我狈蚤,道長困肩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任脆侮,我火速辦了婚禮锌畸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘靖避。我一直安慰自己潭枣,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布幻捏。 她就那樣靜靜地躺著盆犁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪篡九。 梳的紋絲不亂的頭發(fā)上谐岁,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機(jī)與錄音榛臼,去河邊找鬼伊佃。 笑死,一個胖子當(dāng)著我的面吹牛沛善,可吹牛的內(nèi)容都是我干的航揉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼路呜,長吁一口氣:“原來是場噩夢啊……” “哼迷捧!你這毒婦竟也來了织咧?” 一聲冷哼從身側(cè)響起胀葱,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎笙蒙,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡硼婿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了搂抒。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡尿扯,死狀恐怖求晶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情衷笋,我是刑警寧澤芳杏,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站辟宗,受9級特大地震影響爵赵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泊脐,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一空幻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧容客,春花似錦秕铛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至调煎,卻和暖如春镜遣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背士袄。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工悲关, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人娄柳。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓寓辱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親赤拒。 傳聞我的和親對象是個殘疾皇子秫筏,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,514評論 2 348

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