JavaWeb中的Filter過(guò)濾器解讀
Filter過(guò)濾器
Filter過(guò)濾器是JavaWeb的三大組件之一,F(xiàn)ilter過(guò)濾器是JavaEE的規(guī)范也就是接口,F(xiàn)ilter的作用是攔截請(qǐng)求,過(guò)濾響應(yīng)。
攔截請(qǐng)求常見(jiàn)的應(yīng)用場(chǎng)景:權(quán)限檢查、日志操作、事務(wù)管理等等。
Filter過(guò)濾器的基本使用
例如權(quán)限檢查,若沒(méi)有成功驗(yàn)證用戶(hù)信息無(wú)法打開(kāi)目標(biāo)頁(yè)面。
<% Object user = session.getAttribute("user"); if (user == null){ request.getRequestDispatcher("/login.jsp").forward(request,response); return; } %>
用戶(hù)登錄后會(huì)將用戶(hù)登陸信息保存到Session域中,所以要檢查用戶(hù)是否登錄,判斷Session中是否包含用戶(hù)登錄信息。
客戶(hù)端(瀏覽器) -> Filter過(guò)濾器(進(jìn)行權(quán)限檢查,檢查用戶(hù)是否有登錄,如果有權(quán)限則程序默認(rèn)執(zhí)行,如果沒(méi)有權(quán)限控制程序流轉(zhuǎn),不允許其訪問(wèn))
package com.pero.servlet; import jakarta.servlet.*; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; import java.io.IOException; public class AdminFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } /** * doFilter方法專(zhuān)門(mén)用于攔截請(qǐng)求,可以做權(quán)限檢查 * @param servletRequest * @param servletResponse * @param filterChain * @throws IOException * @throws ServletException */ @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //先獲取httpServletRequest對(duì)象,通過(guò)該對(duì)象獲取Session HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; HttpSession session = httpServletRequest.getSession(); Object attribute = session.getAttribute("user"); //表示還沒(méi)有登陸 if (attribute == null){ servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest,servletResponse); }else { //程序繼續(xù)向下執(zhí)行 filterChain.doFilter(servletRequest,servletResponse); } } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version="5.0"> <!-- Filter標(biāo)簽用于配置一個(gè)Filter過(guò)濾器 --> <filter> <!-- 配置Filter別名 --> <filter-name>AdminFilter</filter-name> <!-- 配置Filter全類(lèi)名 --> <filter-class>com.pero.servlet.AdminFilter</filter-class> </filter> <!-- 配置Filter過(guò)濾器的攔截路徑 --> <filter-mapping> <!-- 表示當(dāng)前攔截路徑給哪一個(gè)Filter --> <filter-name>AdminFilter</filter-name> <!-- 配置攔截路徑 /admin/* 表示http://ip:port/工程路徑/ admin目錄下的所有文件 --> <url-pattern>/admin/*</url-pattern> </filter-mapping> <servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>com.pero.servlet.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/loginServlet</url-pattern> </servlet-mapping> </web-app>
package com.pero.servlet; import jakarta.servlet.*; import jakarta.servlet.http.*; import java.io.IOException; public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); String username = request.getParameter("username"); String password = request.getParameter("password"); if ("root".equals(username) && "root".equals(password)){ request.getSession().setAttribute("user",username); response.getWriter().write("登陸成功"); }else { request.getRequestDispatcher("/login.jsp").forward(request,response); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2023/3/16 Time: 22:07 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>登陸頁(yè)面</title> </head> <body> <form action="http://localhost:8080/Filter_Web/loginServlet" method="get"> 用戶(hù)名:<input type="text" name="username"><br/> 密碼:<input type="password" name="password"><br/> <input type="submit" value="提交"> </form> </body> </html>
Filter的生命周期
Filter的生命周期是指Filter從創(chuàng)建到銷(xiāo)毀整個(gè)過(guò)程執(zhí)行方法的順序。包含以下方法:
1.構(gòu)造器方法;
2.init初始化方法;
3.doFilter過(guò)濾方法;
4.destory銷(xiāo)毀方法;
在Web工程啟動(dòng)的時(shí)候構(gòu)造器方法和初始化方法會(huì)被執(zhí)行(Filter對(duì)象已經(jīng)創(chuàng)建),每次攔截到請(qǐng)求時(shí)會(huì)執(zhí)行doFilter方法,停止Web工程的時(shí)候就會(huì)執(zhí)行destory方法。
FilterConfig類(lèi)
FilterConfig類(lèi)是Filter過(guò)濾器的配置文件類(lèi),Tomcat每次創(chuàng)建Filter的時(shí)候也會(huì)同時(shí)創(chuàng)建一個(gè)FilterConfig類(lèi),這里面包含了Filter配置文件的配置信息。
FilterConfig類(lèi)的作用是獲取Filter過(guò)濾器的配置內(nèi)容
1.獲取Filter的名稱(chēng)filter-name的內(nèi)容
2.獲取web.xml配置的init-param初始化參數(shù)
3.獲取ServletContext對(duì)象
package com.pero.servlet; import jakarta.servlet.*; import java.io.IOException; public class TestFilter implements Filter { public TestFilter() { System.out.println("構(gòu)造方法"); } public void init(FilterConfig config) throws ServletException { System.out.println("init初始化方法"); //獲取Filter的名稱(chēng)filter-name的內(nèi)容 String filterName = config.getFilterName(); //獲取web.xml配置的init-param初始化參數(shù) System.out.println("filter-name為:" + filterName); String username = config.getInitParameter("username"); String url = config.getInitParameter("url"); System.out.println("username:" + username + "url:" + url); //獲取ServletContext對(duì)象 ServletContext servletContext = config.getServletContext(); System.out.println("servletContext:" + servletContext); } public void destroy() { System.out.println("destory銷(xiāo)毀方法"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { System.out.println("doFilter方法"); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version="5.0"> <!-- Filter標(biāo)簽用于配置一個(gè)Filter過(guò)濾器 --> <filter> <!-- 配置Filter別名 --> <filter-name>AdminFilter</filter-name> <!-- 配置Filter全類(lèi)名 --> <filter-class>com.pero.servlet.AdminFilter</filter-class> </filter> <filter> <filter-name>TestFilter</filter-name> <filter-class>com.pero.servlet.TestFilter</filter-class> <init-param> <param-name>username</param-name> <param-value>root</param-value> </init-param> <init-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/test</param-value> </init-param> </filter> <filter-mapping> <filter-name>TestFilter</filter-name> <url-pattern>/testFilter</url-pattern> </filter-mapping> <!-- 配置Filter過(guò)濾器的攔截路徑 --> <filter-mapping> <!-- 表示當(dāng)前攔截路徑給哪一個(gè)Filter --> <filter-name>AdminFilter</filter-name> <!-- 配置攔截路徑 /admin/* 表示http://ip:port/工程路徑/ admin目錄下的所有文件 --> <url-pattern>/admin/*</url-pattern> </filter-mapping> <servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>com.pero.servlet.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/loginServlet</url-pattern> </servlet-mapping> </web-app>
FilterChain過(guò)濾器鏈
客戶(hù)端(瀏覽器) -> 服務(wù)器(Filter①:執(zhí)行doFilter()方法:前置代碼1 ->chain.doFilter(request, response); -> Filter②:執(zhí)行doFilter()方法 :前置代碼1 -> chain.doFilter(request, response); -> 查詢(xún)目標(biāo)資源,找到并獲取 -> 后置代碼2 ->Filter①:執(zhí)行doFilter()方法:后置代碼2)
FilterChain.doFilter()方法的作用:①如果有其他的Filter過(guò)濾器,執(zhí)行下一個(gè)Filter過(guò)濾器;②如果沒(méi)有其他需要執(zhí)行的過(guò)濾器,執(zhí)行目標(biāo)資源。
多個(gè)Filter過(guò)濾器執(zhí)行的時(shí)候他們執(zhí)行的優(yōu)先順序是由在web.xml中filter-mapping從上到下的配置順序決定的。
多個(gè)Filter過(guò)濾器執(zhí)行的特點(diǎn):
①所有Filter和目標(biāo)資源默認(rèn)都執(zhí)行在同一個(gè)線程中
②多個(gè)Filter共同執(zhí)行的時(shí)候,他們都使用同一個(gè)Request對(duì)象。
package com.pero.servlet; import jakarta.servlet.*; import java.io.IOException; import java.lang.Thread; public class Filter1 implements Filter { public void init(FilterConfig config) throws ServletException { } public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { System.out.println("Filter1前置代碼"); System.out.println("Filter1線程" + Thread.currentThread().getName()); System.out.println("Filter1" + request.getParameter("username")); chain.doFilter(request, response); System.out.println("Filter1線程" + Thread.currentThread().getName()); System.out.println("Filter1后置代碼"); } }
package com.pero.servlet; import jakarta.servlet.*; import java.io.IOException; public class Filter2 implements Filter { public void init(FilterConfig config) throws ServletException { } public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { System.out.println("Filter2前置代碼"); System.out.println("Filter2線程"+Thread.currentThread().getName()); System.out.println("Filter2" + request.getParameter("username")); chain.doFilter(request, response); System.out.println("Filter2線程"+Thread.currentThread().getName()); System.out.println("Filter2后置代碼"); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version="5.0"> ... <filter> <filter-name>Filter1</filter-name> <filter-class>com.pero.servlet.Filter1</filter-class> </filter> <filter> <filter-name>Filter2</filter-name> <filter-class>com.pero.servlet.Filter2</filter-class> </filter> <filter-mapping> <filter-name>Filter1</filter-name> <url-pattern>/target.jsp</url-pattern> </filter-mapping> <filter-mapping> <filter-name>Filter2</filter-name> <url-pattern>/target.jsp</url-pattern> </filter-mapping> ... </web-app>
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2023/3/17 Time: 10:30 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% System.out.println("target頁(yè)面執(zhí)行"); System.out.println("目標(biāo)資源"+Thread.currentThread().getName()); System.out.println("目標(biāo)資源" + request.getParameter("username")); %> </body> </html>
Filter的攔截路徑
精確匹配
<url-pattern>/admin/*</url-pattern>
以上配置路徑表示請(qǐng)求地址必須為://ip:port/工程路徑/target.jsp
目標(biāo)匹配
<url-pattern>/admin/*</url-pattern>
以上配置的路徑,表示請(qǐng)求地址必須為://ip:port/工程路徑/admin/*
后綴名匹配
<url-pattern>*.html</url-pattern>
以上配置路徑,表示請(qǐng)求地址必須為:.html
Filter過(guò)濾器只關(guān)心請(qǐng)求的值是否匹配,不關(guān)心資源是否存在
到此這篇關(guān)于JavaWeb中的Filter過(guò)濾器解讀的文章就介紹到這了,更多相關(guān)Filter過(guò)濾器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java使用EasyExcel進(jìn)行單元格合并的問(wèn)題詳解
項(xiàng)目中需要導(dǎo)出并合并指定的單元格,下面這篇文章主要給大家介紹了關(guān)于java評(píng)論、回復(fù)功能設(shè)計(jì)與實(shí)現(xiàn)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06vscode開(kāi)發(fā)maven的javaweb項(xiàng)目并部署到tomcat及配置指南
這篇文章主要給大家介紹了關(guān)于vscode開(kāi)發(fā)maven的javaweb項(xiàng)目并部署到tomcat及配置的相關(guān)資料,在vscode中創(chuàng)建maven項(xiàng)目,需要逐一操作下面的環(huán)節(jié),文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12Java基礎(chǔ)之面向?qū)ο髾C(jī)制(多態(tài)、繼承)底層實(shí)現(xiàn)
這篇文章主要介紹了Java基礎(chǔ)之面向?qū)ο髾C(jī)制(多態(tài)、繼承)底層實(shí)現(xiàn),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04springboot實(shí)現(xiàn)異步任務(wù)
這篇文章主要為大家詳細(xì)介紹了springboot實(shí)現(xiàn)異步任務(wù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05IDEA中Maven報(bào)錯(cuò)Cannot resolve xxx的解決方法匯總(親測(cè)有效)
在IDEA中的pom文件中添加了依賴(lài),并且正確加載了相應(yīng)依賴(lài),pom文件沒(méi)有報(bào)紅,看起來(lái)像是把所有依賴(lài)庫(kù)全部加載進(jìn)來(lái)了,但是代碼中使用依賴(lài)的類(lèi)庫(kù)使報(bào)紅,本文給大家介紹了IDEA中Maven報(bào)錯(cuò)Cannot resolve xxx的解決方法匯總,需要的朋友可以參考下2024-06-06java中將一個(gè)實(shí)體類(lèi)復(fù)制到另一個(gè)實(shí)體類(lèi)的3種方法示例
這篇文章主要給大家介紹了關(guān)于java中將一個(gè)實(shí)體類(lèi)復(fù)制到另一個(gè)實(shí)體類(lèi)的3種方法,所謂實(shí)體類(lèi)就是一個(gè)擁有Set和Get方法的類(lèi),文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07Java中BufferedReader和BufferedWriter使用方式
這篇文章主要介紹了Java中BufferedReader和BufferedWriter使用方式,F(xiàn)ileWriter?類(lèi)從?OutputStreamWriter?類(lèi)繼承而來(lái),BufferedReader?類(lèi)從字符輸入流中讀取文本并緩沖字符,以便有效地讀取字符,數(shù)組和行2022-06-06PowerJob的GridFsManager工作流程源碼解讀
這篇文章主要為大家介紹了PowerJob的GridFsManager工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01