JavaWeb-過濾器(Filter)

1. Filter簡介

Filter也稱之為過濾器,WEB開發(fā)人員通過Filter技術(shù),對web服務(wù)器管理的所有web資源:例如Jsp ,Servlet ,靜態(tài)圖片文件或靜態(tài)html文件等進(jìn)行攔截,從而實現(xiàn)一些特殊的功能。

Servlet API中提供了一個Filter接口 ,開發(fā)web應(yīng)用時,如果編寫的類實現(xiàn)了這個接口,則把這個java類稱之為過濾器Filter。通過Filter技術(shù) ,開發(fā)人員可以實現(xiàn)用戶在訪問某個目標(biāo)資源之前,對訪問的請求和響應(yīng)進(jìn)行攔截,如下所示:


image.png
image.png

Filter開發(fā)入門

Filter開發(fā)步驟

Filter開發(fā)分為二個步驟:

  • 編寫java類實現(xiàn)Filter接口,并實現(xiàn)其doFilter方法。
  • 在web.xml(不使用注解方式)文件中使用<filter>和<filter-mapping>元素對編寫的filter類進(jìn)行注冊,并設(shè)置它所能攔截的資源。(了解即可,百度)

2. Filter是如何實現(xiàn)攔截的?

Filter接口中有一個doFilter方法, 當(dāng)我們編寫好Filter,并配置對哪個web資源進(jìn)行攔截后,WEB服務(wù)器每次在調(diào)用web資源的service方法之前,都會先調(diào)用一下filter的doFilter方法,因此,在該方法內(nèi)編寫代碼可達(dá)到如下目的:

調(diào)用目標(biāo)資源之前,讓一段代碼執(zhí)行。
是否調(diào)用目標(biāo)資源(即是否讓用戶訪問web資源)
web服務(wù)器在調(diào)用doFilter方法時,會傳遞一個filterChain對象進(jìn)來 ,filterChain對象是filter接口中最重要的一個對象,它也提供了一個doFilter方法,開發(fā)人員可以根據(jù)需求決定是否調(diào)用此方法,調(diào)用該方法,則web服務(wù)器就會調(diào)用web資源的service方法,即web資源就會被訪問,否則web資源不會被訪問。
調(diào)用目標(biāo)資源之后,讓一段代碼執(zhí)行。

3. 過濾器簡單代碼

主頁面 index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <a href="a.do?username=zhangsan">訪問Aservlet</a>
  <a href="b.do?username=lisi">訪問Bservlet</a>
  <a href="c.action?username=lisi">訪問Cservlet</a>
  </body>
</html>

a.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
放行了.... a.jsp
</body>
</html>

b.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
過濾器打回了... b.jsp
</body>
</html>

過濾器

package com.lty.filter;

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

@WebFilter(filterName = "TestFilter" , urlPatterns = "*.do")
public class TestFilter implements Filter {
    public void destroy() {
        System.out.println("TestFilter destroy");
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        String username = req.getParameter("username");


        System.out.println("doFilter before");
        if(username.equals("zhangsan")){
            chain.doFilter(req, resp); //放行了
        }else{
            req.getRequestDispatcher("b.jsp").forward(req,resp);
        }

        System.out.println("doFilter after");
    }

    public void init(FilterConfig config) throws ServletException {
        System.out.println("TestFilter init");
    }

}

servlet

package com.lty.servlet;

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 = "AServlet" , urlPatterns = "/a.do")
public class AServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("AServlet");
        request.getRequestDispatcher("a.jsp").forward(request,response);
    }
}
package com.lty.servlet;

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 = "BServlet" , urlPatterns = "/b.do")
public class BServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("BServlet");
    }
}
package com.lty.servlet;

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 = "CServlet" , urlPatterns = "/c.action")
public class CServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("CServlet");
        request.getRequestDispatcher("a.jsp").forward(request,response);
    }
}

4. 過濾器的生命周期

Filter對象何時被創(chuàng)建?
服務(wù)器一啟動的時候,就會針對這個web應(yīng)用將所有的Filter對象(攔截器)創(chuàng)建出來,并且以后訪問的時候,都是使用同一個攔截器進(jìn)行攔截。也即一個攔截器會被所有的請求所共享,每一次請求來了之后,都會導(dǎo)致doFilter()方法被調(diào)用一次,F(xiàn)ilter對象只有一個,而doFilter()方法會被多次調(diào)用。
問: Filter對象在內(nèi)存里面有幾個?
答:一個。服務(wù)器并不會針對請求創(chuàng)建新的Filter對象(攔截器)。
Filter對象何時被摧毀?
移除掉web服務(wù)器里面這個web應(yīng)用(或停掉服務(wù)器),就會摧毀這個web應(yīng)用對應(yīng)的攔截器。

使用過濾器技術(shù)解決中文亂碼問題(統(tǒng)一全站的編碼)

package com.lty.filter;

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

@WebFilter(filterName = "CoderFilter" , urlPatterns = "*.do")
public class CoderFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }

}
image.png

5. 過濾器應(yīng)用

主頁面 index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <a href="login.do">登錄</a>
  <a href="admin.admin">進(jìn)入管理后臺界面</a>
  </body>
</html>

登錄頁面 login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="login.do" method="post">
    <input type="text" name="username">
    <input type="submit" value="登錄">
</form>
</body>
</html>

admin.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
我是整個網(wǎng)站的后臺管理員頁面首頁
</body>
</html>

student.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
我是整個網(wǎng)站的后臺學(xué)生信息管理頁面
</body>
</html>

監(jiān)聽器

package com.lty.filter;

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

@WebFilter(filterName = "AuthFilter" , urlPatterns = "*.admin")
public class AuthFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest)req;

        Object obj = request.getSession().getAttribute("user");
        if(obj != null){
            chain.doFilter(req, resp);
        }else{
            request.getRequestDispatcher("login.jsp").forward(request,resp);
        }

    }

    public void init(FilterConfig config) throws ServletException {

    }

}

servlet

package com.lty.servlet;

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.do")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        request.getSession().setAttribute("user",username);
        request.getRequestDispatcher("/WEB-INF/admin.jsp").forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("login.jsp").forward(request,response);
    }
}
package com.lty.servlet;

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 = "AdminServlet" , urlPatterns = "/admin.admin")
public class AdminServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("/WEB-INF/admin.jsp").forward(request,response);// WEB-INF前面的 / 代表該項目中的web文件
    }
}
package com.lty.servlet;

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 = "StudentServlet" , urlPatterns = "/student.admin")
public class StudentServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("/WEB-INF/student.jsp").forward(request,response);// WEB-INF前面的 / 代表該項目中的web文件
    }
}
image.png

6. 過濾器其它

當(dāng)一個項目使用多個過濾器的時候,默認(rèn)項目中第一個(靠前的)過濾器進(jìn)行首次攔截


image.png

凡是放到WEB-INF目錄下的文件,Tomcat服務(wù)器規(guī)定用戶無法在瀏覽器上進(jìn)行訪問(用戶通過輸入網(wǎng)址的方式進(jìn)行訪問)


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容