1. 程式人生 > >Java EE Web部分--06.Filter過濾器

Java EE Web部分--06.Filter過濾器

一、概述

濾器(filter):本質是Java中預先定義好了不同的介面,可以過濾不同的內容,在專案中,我們對訪問某些資源的請求需要進條件的篩選、過濾時、就需要使用者定義一個實現類,然後實現介面中的過濾方法,在方法中書寫過濾的條件。filter是對客戶端訪問資源的過濾,符合條件放行,不符合條件不放行。

應用:1、過濾論動中的非法字元

           2、登入許可權檢查

API:

void init(FilterConfig  filterConfig); //過濾器物件建立的時候呼叫的方法

void doFilter(ServletRequest request, ServletResponse response, FilterChain chain);//執行過濾的方法

void destory();//過濾器銷燬的時候呼叫的方法

開發步驟:

步驟一:新建一個java類、實現Filter介面

步驟二:重寫Filter介面的3個方法

步驟三:類上面配置註解

@WebFilter  配置Filter的註解

filterName;設定過濾器的名稱 

urlPatterns 配置這個過濾器要攔截的資源的路徑

步驟四:在doFilter()方法中、書寫過濾的業務邏輯

chain.doFilter()方法放行

演示:

Servlet程式碼、LoginServlet.java

package com.mvcCase.Test;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "LoginServlet", urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //重定向到首頁
        response.sendRedirect("index.jsp");
    }
}

MyFilter.java

package com.mvcCase.Test;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@WebFilter(filterName = "MyFilter", urlPatterns = {"/login","/index.jsp"})
public class MyFilter implements Filter {

    public void init(FilterConfig config) throws ServletException {

    }
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //執行過濾的方法

        //將ServletRequest物件強轉成HttpServletRequest物件
        HttpServletRequest request = (HttpServletRequest) req;
        //獲取請求路徑
        StringBuffer url = request.getRequestURL();
        System.out.println("攔截了請求:"+url);
        //放行
        chain.doFilter(request,resp);
    }
    public void destroy() {
    }
}

二、過濾器的執行流程

過濾器的doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)方法中的request物件和response物件並不是過濾器自己建立的。而是,從被過濾的資源中傳遞過來的。過濾器的執行流程如下:

1. 客戶端(瀏覽器)的HttpRequest到達Servlet之前,被Filter的doFilter()方法攔截;
2. 根據需要,我們可以獲取或者修改HttpRequest物件中的資料;
3. 在這個請求響應給瀏覽器之前,Filter攔截了HttpResponse物件;
4. 根據需要,我們可以獲取或者修改HttpReponse物件中的資料;
5. 最後,由doFilter中的chain決定是否讓這個請求通過;

 

三、Filter生生命週期

1、Filter類的物件是在伺服器啟動的時候建立的;

2、Filter類物件建立完成後會呼叫init()方法;

3、只要一個請求符合Filter攔截路徑、瀏覽器請求一次、就會被doFilter方法攔截、

4、伺服器停止、呼叫destory方法

演示:

package com.mvcCase.Test;

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


@WebFilter(filterName = "LifeFilter",urlPatterns = "/login")
public class LifeFilter implements Filter {

    /**
     * 顯示建立這個類的無參構造方法
     */
    public LifeFilter() {
        System.out.println("LifecycleFilter物件被建立了.................");
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("LifecycleFilter的init方法被執行了.......................");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("LifecycleFilter的doFilter方法執行了..............");
    }

    @Override
    public void destroy() {
        System.out.println("LifecycleFilter的destory方法執行了.......................");
    }
}

 

doFilter()方法

​ doFilter()方法是攔截請求的方法,只要一個請求符合Filter攔截路徑,都會被doFilter()方法攔截。doFilter()方法有3個引數,這3個引數的作用分別如下:

引數 說明
ServletRequest req ServletRequest是HttpServletRequest類的父類,其中包含了被攔截的請求的資訊
ServletResponse resp ServletResponse是HttpServletResponse類的父類,其中包含了被攔截的響應的資訊
FilterChain chain FilterChain給Filter提供了放行的方法。chain.doFilter();

四、Filter對映路徑

1、精確匹配

​ 精確匹配,要求訪問的資源路徑必須與Filter的urlPatterns中的配置一致。如下:

精確匹配 說明
urlPatterns = "/index.jsp" 攔截對index.jsp頁面的請求
urlPatterns = "/loginServlet" 攔截對loginServlet的請求
urlPatterns = "/a.jpg" 攔截對a.jsp的請求

Filter的urlPatterns引數中也可以一次性配置多個路徑,如下:

精確匹配 說明
urlPatterns = {"/login.jsp","/descServlet"} 既能攔截login.jsp又攔截descServlet的請求

2、模糊匹配

模糊匹配主要有以下3種寫法:

模糊匹配 使用示例 說明
urlPatterns = "/*" urlPatterns = "/*" 對所有的請求都進行攔截
urlPatterns = "/xxx/*" urlPatterns = "/user/*" 對對映路徑中/user下的所有資源進行攔截
urlPatterns = "*.xxx" urlPatterns = "*.jsp" 對指定字尾的請求進行攔截

五、Filter應用案例

1、Filter統一解決post請求亂碼問題

8.0版本以上的tomcat為我們解決了get請求的亂碼問題。我們需要自己處理post請求的亂碼問題,因為我們的一個專案中可能有很多的請求。這時就可以用Filter來處理了。

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter(filterName = "AEncodeFilter",urlPatterns = "/demoServlet")
public class AEncodeFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //響應的亂碼的處理
        HttpServletResponse response = (HttpServletResponse)resp;
        response.setContentType("text/html;charset=utf-8");

        //post請求的亂碼處理
        HttpServletRequest request = (HttpServletRequest)req;
        String method = request.getMethod();
        if("POST".equals(method)){
            req.setCharacterEncoding("utf-8");
        }
        //放行
        chain.doFilter(req, resp);
    }
    public void init(FilterConfig config) throws ServletException {
    }
}

2、非法字元過濾器

說明:

1.建立一個表單用於發表言論。 

2.建立一個txt檔案,其中存入非法字元。 

3.建立一個Filter,攔截請求。在init方法中將txt檔案中的非法字元讀取到記憶體中。 

4.獲取請求中的引數,對請求的引數進行非法字元的校驗。

5.如果言論中不含有非法字元,就放行。 

6.如果言論中含有非法字元,就攔截,並且提示使用者非法言論 

form.jsp表單

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/wordsServlet" method="post">
    使用者名稱:<input type="text" name="username"><br>
    評論:<textarea name="desc"></textarea><br>
    <input type="submit" value="提交">
</form>
</body>
</html>

WordsServlet.java

package com.filter.errorwords;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/wordsServlet")
public class wordsServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
//
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;character=utf-8");
        String str = request.getParameter("username");
        String str1 = request.getParameter("desc");
        response.getWriter().print("context is true ="+str+str1);

    }
}

WordsFilter.java 過濾器

package com.filter.errorwords;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.*;

@WebFilter(filterName = "WordsFilter",urlPatterns = {"/wordsServlet"})
public class WordsFilter implements Filter {
    StringBuffer sb = new StringBuffer();
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        request.setCharacterEncoding("utf-8");

//        HttpServletResponse response = (HttpServletResponse) resp;
//        response.setContentType("text/html;character=utf-8");

       String desc = request.getParameter("desc");
//        System.out.println("desc = " + desc);
        if (sb.toString().contains(desc)){
            System.out.println("內容敏感,重新提交");
            resp.getWriter().print("內容敏感、重新提交");
            return;
        }
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {
        String realPath = config.getServletContext().getRealPath("disu.txt");
        String line = null;
        try {
            InputStreamReader isr = new InputStreamReader(new FileInputStream(realPath),"utf-8");
            BufferedReader br = new BufferedReader(isr);
            while ((line = br.readLine()) != null){
                sb.append(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("sb"+sb.toString());
    }

}