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

前言

springmvc中有兩種很普遍的AOP實現:
1.過濾器(Filter)
2.攔截器(Interceptor)

本篇面對的是一些剛接觸springboot的人羣
所以主要講解filter和interceptor的簡單實現和它們之間到底有什麼區別
(一些複雜的功能我會之後發出文章,請記得關注)

Filter的簡單實現

字面意思:過濾器就是過濾的作用,在web開發中過濾一些我們指定的url
那麼它能幫我們過濾什麼呢?
那功能可就多了:
比如過攔截掉我們不需要的接口請求
修改請求(request)和響應(response)內容
完成CORS跨域請求等等

現在我們來實現一個簡單的過濾器:
可以新建一個filter包,隨着項目的擴大過濾器會越來越多
在這裏我新建了一個TestFilter類,實現Filter接口

@Component
@WebFilter(urlPatterns = "/Blogs",filterName = "blosTest")
public class TestFilter implements Filter{}

我們一步步來
1.@Component就是把這個類注入到IOC容器中
2.@WebFilter(urlPatterns = "/Blogs",filterName = "blosTest")說明這是一個web過濾器,它攔截的url爲/Blogs,過濾器名字爲blogsTest

下面貼出實現接口之後的三個重構方法:

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

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request= (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        System.out.printf("過濾器實現");
        filterChain.doFilter(request,response);
    }

    @Override
    public void destroy() {

    }

初始化(init)和摧毀(destroy)方法一般不會用到,具體使用看下源碼便知
doFilter()是過濾器的核心
注意:在實現接口方法之後,我們要轉換request和response類型至HttpServlet,否則接下去的操作可能會報錯。
如果過濾通過,執行filterChain.doFilter(request,response);
說明這個url已經經過了我們的Filter
其他不要設置,我們執行看下結果:

clipboard.png

clipboard.png

可以看到,只需要一個類我們就實現了一個簡單的過濾器

當然可以不用註解的方式,配置啓動類

//過濾器
    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        List<String> urlPatterns = new ArrayList<String>();

        TestFilter testFilter = new TestFilter();   //new過濾器
        urlPatterns.add("/Blogs");      //指定需要過濾的url
        filterRegistrationBean.setFilter(testFilter);       //set
        filterRegistrationBean.setUrlPatterns(urlPatterns);     //set

        return filterRegistrationBean;
    }

這也是可以的,本人其實還是比較推薦這種方式添加過濾器

Interceptor的簡單實現

攔截器的實現比過濾器稍微複雜一點
我們同樣可以新建一個interceptor包
在裏面新建一個名爲MyInterceptor的類

public class MyInterceptor implements HandlerInterceptor {}

這個類實現了HandleInterceptor接口
直接貼類代碼,我會在代碼中註釋功能

public class MyInterceptor implements HandlerInterceptor {
    //在請求處理之前進行調用(Controller方法調用之前
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.printf("preHandle被調用");
        return true;    //如果false,停止流程,api被攔截
    }

    //請求處理之後進行調用,但是在視圖被渲染之前(Controller方法調用之後)
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle被調用");
    }

    //在整個請求結束之後被調用,也就是在DispatcherServlet 渲染了對應的視圖之後執行(主要是用於進行資源清理工作)
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("afterCompletion被調用");
    }
}

它依次實現了三個方法
相比過濾器,攔截器還需要在springmvc中注入
所以我們打開啓動類,寫入以下代碼

public class WarApplication {

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

    //mvc控制器
    //@Configuration
    static class WebMvcConfigurer extends WebMvcConfigurerAdapter{
        //增加攔截器
        public void addInterceptors(InterceptorRegistry registry){
            registry.addInterceptor(new MyInterceptor())    //指定攔截器類
                    .addPathPatterns("/Handles");        //指定該類攔截的url
        }
    }
}

這裏我在/Handles這個url中進行攔截
代碼寫完了,來看下結果

clipboard.png

clipboard.png

當進入指定url時,我們執行到了攔截器
接下來就可以根據需求去使用攔截器了

區別

過濾器和攔截器非常相似,但是它們有很大的區別
最簡單明瞭的區別就是過濾器可以修改request,而攔截器不能
過濾器需要在servlet容器中實現,攔截器可以適用於javaEE,javaSE等各種環境
攔截器可以調用IOC容器中的各種依賴,而過濾器不能
過濾器只能在請求的前後使用,而攔截器可以詳細到每個方法

區別很多,大家可以去查下

總的來說
過濾器就是篩選出你要的東西,比如requeset中你要的那部分
攔截器在做安全方面用的比較多,比如終止一些流程
網上有一張圖片很不錯,這裏拷過來給大家看一下

clipboard.png

以上便是springboot中過濾器和攔截器的實現和區別;
覺得還可以的請點個贊,贊不了也可以收藏下;
總之,謝謝閱讀~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章