天天看點

過濾器Filter總結+案例-實作敏感詞彙過濾

過濾器Filter案例-實作敏感詞彙過濾

Filter概念: web中的過濾器:當通路伺服器的資源時,過濾器可以将請求攔截下來,完成一些特殊的功能。

過濾器的作用:

  1. 一般用于完成通用的操作,如:登陸驗證,統一編碼處理、敏感字元過濾…等。
  2. Filter過濾器能夠在Servlet被調用之前檢查Request對象,并修改Request Header和Request内容;在Servlet被調用之後檢查Response對象,修改Response Header和Response的内容,實作多次過濾。
  3. Filter可以過濾的web元件包括Servlet,JSP和HTML等檔案。

Filter的過濾原理

當浏覽器向伺服器發出資源的請求時,當浏覽器滿足過濾條件時,Web伺服器根據應用程式配置檔案設定的過濾規則進行檢查。是一次雙向過濾的過程

過濾器Filter總結+案例-實作敏感詞彙過濾

過濾器生命周期方法

init()方法:在伺服器啟動後,會建立filter對象,然後調用init方法。隻執行一次,用于加載資源。

doFilter()方法:每一次請求被攔截資源時,會執行,執行多次。

destroy()方法:在伺服器關閉後,filter對象會被銷毀,如果伺服器時正常關閉,則會執行destroy方法,隻執行一次,用于釋放資源。

過濾器鍊(配置多個過濾器)

執行順序:如果有兩個過濾器:過濾器1,過濾器2

過濾器1–>過濾器2–>資源執行–>(傳回)–>過濾器2–>過濾1

過濾器先後順序問題:

注解配置:按照類名的字元串比較規則比較,值小的先執行。

如:Afilter 和 Bfilter,A<B A先執行

過濾器配置

攔截方式配置:dispatcherTypes 資源通路的方式:

//假如時浏覽器直接請求index.jsp路徑,那麼将直接攔截,轉發到該路徑則不予阻攔
@WebFilter(value = "/index.jsp", dispatcherTypes = DispatcherType.REQUEST)
	//釋放代碼
   chain.doFilter(req, resp);
           
過濾器Filter總結+案例-實作敏感詞彙過濾

案例敏感詞的過濾:

代理模式詳解圖:(靈魂畫手)、反正意思就似乎用上代理類,效率高,還能過濾掉敏感詞彙

過濾器Filter總結+案例-實作敏感詞彙過濾

為什麼要用代理模式?

中介隔離作用:在某些情況下,一個客戶類不想或者不能直接引用一個委托對象,而代理類對象可以在客戶類和委托對象之間起到中介的作用,其特征是代理類和委托類實作相同的接口。

接下來就是實作代理模式

** public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        String name = req.getParameter("name");
       //動态代理增強,增強getParameter方法
        /* 三個參數:
                1. 類加載器:真實對象.getClass().getClassLoader()
                2. 接口數組:真實對象.getClass().getInterfaces()
                3. 處理器:new InvocationHandler()
           這邊的真實對象就是ServletRequest req的參數;
         */
        ServletRequest ser = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         /*   代理邏輯編寫的方法:代理對象調用的所有方法都會觸發該方法執行
                    參數:1. proxy:代理對象
                         2. method:代理對象調用的方法,被封裝為的對象
                         3. args:代理對象調用的方法時,傳遞的實際參數
             */
                //判斷是不是getParameter方法
                if (method.getName().equals("getParameter")){
               	  //使用真實對象調用該方法
                    String invoke = (String) method.invoke(req, args);
                    //假如傳回的值不為空,則進行敏感字元過濾
                    if (invoke != null ){
                        for (String s : list) {
                            if (invoke.contains(s)){
                                invoke = invoke.replaceAll(s,"***");
                            }
                        }
                    }
                    return invoke;
                }
                return method.invoke(req,args);
            }
        });
        String name1 = ser.getParameter("name");
        String rows = ser.getParameter("rows");
        System.out.println(rows);
        chain.doFilter(ser, resp);

    }
    
	//init方法在第一時間進行執行,并且隻會執行一次。把每對敏感字元存入到list集合中
    private List<String> list = new ArrayList<>();
    @Override
    public void init(FilterConfig config) throws ServletException {
        //擷取路徑
        try {
            ServletContext servletContext = config.getServletContext();
            String realPath = servletContext.getRealPath("//WEB-INF//classes//敏感詞彙.txt");
            //防止亂碼 用InputStreamReade是從位元組流到字元流的橋梁。
            BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileInputStream(realPath),"gbk"));
            String len = null;
            while ((len = bufr.readLine()) != null){
                list.add(len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }**
           
過濾器Filter總結+案例-實作敏感詞彙過濾

效果展示:

你是壞蛋,王八蛋
你是***,***
你是***,***