servlet過濾器有什麼做用,通常用在什麼地方??_樂字節java

過濾器

介紹

​ Filter 即爲過濾,用於在 Servlet 以外對 Request 或者 Response 進行修改。它主要用於對用戶請求進行預處理,也能夠對 HttpServletResponse 進行後處理。使用 Filter 的完整流程: Filter 對用戶請求進行預處理,接着將請求交給 Servlet 進行處理並生成響應,最後 Filter 再 對服務器響應進行後處理。在一個 web 應用中,能夠開發編寫多個 Filter,這些 Filter 組合 起來稱之爲一個 Filter 鏈。css

單個過濾器前端

filter_1.png

多個過濾器java

filter_2.png

​ <font color="red">如果一個過濾器鏈:先配置先執行(請求時的執行順序);響應時: 以相反的順序執行。</font>web

​ 在 HttpServletRequest 到達 Servlet 以前,攔截客戶的 HttpServletRequest 。根據須要檢查HttpServletRequest,也能夠修改 HttpServletRequest 頭和數據。 服務器

​ 在HttpServletResponse 到達客戶端以前,攔截 HttpServletResponse。根據須要檢查 HttpServletResponse,也能夠修改 HttpServletResponse頭和數據。session

實現

​ 能夠經過實現一個叫作javax.servlet.Fileter的接口來實現一個過濾器,其中定義了 三個方法,init(), doFilter(), destroy()分別在相應的時機執行。後期觀察生命週期。 app

​ Filter 的實現只須要兩步: jsp

​ Step1: 編寫 java 類實現 Filter 接口,並實現其 doFilter 方法。 ide

​ Step2: 經過@WebFilter註解設置它所能攔截的資源。微服務

@WebFilter("/*")
public class Filter01 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

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

    }

    @Override
    public void destroy() {

    }
}

​ Filter 接口中有一個 doFilter 方法,當開發人員編寫好 Filter,並配置對哪一個 web 資源進行攔截後,Web 服務器每次在調用 web 資源的 service 方法以前,都會先調用一下 filter 的 doFilter 方法。所以能夠達到以下效果:

​ 調用目標資源以前,讓一段代碼執行。

​ 是否調用目標資源(便是否讓用戶訪問 web 資源)。

​ web 服務器在調用 doFilter 方法時,會傳遞一個 filterChain 對象進來,filterChain 對象是 filter 接口中最重要的一個對象,它提供了一個 doFilter 方法,開發人員能夠根據需求決定 是否調用此方法,調用該方法,則 web 服務器就會調用 web 資源的 service 方法,即 web 資源就會被訪問,不然 web 資源不會被訪問。(本質是放行,調用doFilter方法後,即請求能夠到達資源)

實例

請求亂碼處理

/**
 * 字符亂碼處理
 *  亂碼狀況:
                    Tomcat8及以上版本                            Tomcat7及如下版本

        POST請求      亂碼,須要處理                             亂碼,須要處理
                    request.setCharacterEncoding("UTF-8");          

        GET請求
                    不會亂碼,不須要處理                          亂碼,須要處理
            new String(request.getParameter("參數名").getBytes("ISO-8859-1"),"UTF-8");

        如何處理:
            一、處理POST請求
                request.setCharacterEncoding("UTF-8");
            二、處理GET請求且服務器版本在Tomcat8如下的
                1> 獲得請求類型 (GET請求)
                2> 獲得服務器的版本的信息
                3> 判斷是GET請求且Tomcat版本小於8
                4> 處理亂碼
                  new String(request.getParameter("參數名").getBytes("ISO-8859-1"),"UTF-8");

 */
@WebFilter("/*")
public class AEncodingFilter implements Filter {

    public AEncodingFilter() {
    }

    public void destroy() {     
    }

    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException {
        // 基於HTTP
        HttpServletRequest request = (HttpServletRequest) arg0;
        HttpServletResponse response = (HttpServletResponse) arg1;

        // 處理請求亂碼亂碼 (處理POST請求)
        request.setCharacterEncoding("UTF-8");  

        // 處理GET請求且服務器版本在Tomcat8如下的
        String method = request.getMethod();
        // 若是是GET請求
        if ("GET".equalsIgnoreCase(method)) {
            // 服務器版本在Tomcat8如下的 Apache Tomcat/8.0.45
            String serverInfo = request.getServletContext().getServerInfo();            
            // 獲得具體的版本號
            String versionStr = serverInfo.substring(serverInfo.indexOf("/")+1, serverInfo.indexOf("."));
            // 判斷服務器版本是否小於8
            if (Integer.parseInt(versionStr) < 8) {
                // 獲得自定義內部類  (MyWapper繼承了HttpServletRequestWapper對象,而HttpServletRequestWapper對象實現了HttpServletRequest接口,因此MyWapper的本質也是request對象)
                HttpServletRequest myRequest = new MyWapper(request);
                // 放行資源
                chain.doFilter(myRequest, response);
                return;
            }
        }

        // 放行資源
        chain.doFilter(request, response);      
    }

    public void init(FilterConfig fConfig) throws ServletException {

    }

    /**
     * 定義內部類,繼承HttpServletRequestWrapper包裝類對象,重寫getParameter()方法
     */
    class MyWapper extends HttpServletRequestWrapper {

        // 定義成員變量,提高構造器 中的request對象的範圍
        private HttpServletRequest request;

        public MyWapper(HttpServletRequest request) {
            super(request);
            this.request = request;
        }

        /**
         * 重寫getParameter()方法
         */
        @Override
        public String getParameter(String name) {
            String value = request.getParameter(name);

            if (value != null && !"".equals(value.trim())) {
                try {
                    // 將默認ISO-8859-1編碼的字符轉換成UTF-8
                    value = new String(value.getBytes("ISO-8859-1"),"UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
            return value;
        }
    }
}

用戶非法訪問攔截

/**
 * 非法訪問攔截(當用戶未登陸時,攔截請求到登陸頁面)
 *      攔截的資源:
 *          攔截全部資源  /*
 *      須要被放行的資源:
 *          不須要登陸便可訪問的資源
 *          一、放行指定頁面,不須要登陸能夠訪問的頁面 (例如:登陸頁面、註冊頁面等)
 *          二、放行靜態資源(例如:css、js、image等資源)
 *          三、放行指定操做,不須要登陸便可執行的操做(例如:登陸操做、註冊操做等)
 *          四、登陸狀態放行 (若是存在指定sessuin對象,則爲登陸狀態)
 */ 
@WebFilter("/*")
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException {

        // 基於HTTP
        HttpServletRequest request = (HttpServletRequest) arg0;
        HttpServletResponse response = (HttpServletResponse) arg1;
        // 獲得請求的路徑
        String path = request.getRequestURI(); //   站點名/資源路徑    
        // 一、放行指定頁面,不須要登陸能夠訪問的頁面 (例如:登陸頁面、註冊頁面等)
        if (path.contains("/login.jsp") || path.contains("/register.jsp")) {
             chain.doFilter(request, response);
             return;
        }
        // 二、放行靜態資源(例如:css、js、image等資源)
        if (path.contains("/js")) {
             chain.doFilter(request, response);
             return;
        }
        // 三、放行指定操做,不須要登陸便可執行的操做(例如:登陸操做、註冊操做等)
        if (path.contains("/loginServlet")) {
             chain.doFilter(request, response);
             return;
        }
        // 四、登陸狀態放行 (若是存在指定sessuin對象,則爲登陸狀態)
        // 獲得session域對象
        String uname = (String) request.getSession().getAttribute("user");
        // 若是session域對象不爲空,則爲登陸狀態,放行資源
        if (uname != null && !"".equals(uname.trim())) {
            chain.doFilter(request, response);
             return;
        }   

        // 若以上條件均不知足,攔截跳轉到登陸頁面
        response.sendRedirect("login.jsp");
        return;
    }

想要更多Java,前端,大數據,微服務等資料<a href="https://i.loli.net/2020/06/22/zbPOtKIqDjo45Mw.png">點我掃碼領取</a>;

相關文章
相關標籤/搜索