JavaWeb中的Filter過濾器解讀
Filter過濾器
Filter過濾器是JavaWeb的三大組件之一,F(xiàn)ilter過濾器是JavaEE的規(guī)范也就是接口,F(xiàn)ilter的作用是攔截請求,過濾響應。
攔截請求常見的應用場景:權限檢查、日志操作、事務管理等等。
Filter過濾器的基本使用
例如權限檢查,若沒有成功驗證用戶信息無法打開目標頁面。
<%
Object user = session.getAttribute("user");
if (user == null){
request.getRequestDispatcher("/login.jsp").forward(request,response);
return;
}
%>用戶登錄后會將用戶登陸信息保存到Session域中,所以要檢查用戶是否登錄,判斷Session中是否包含用戶登錄信息。
客戶端(瀏覽器) -> Filter過濾器(進行權限檢查,檢查用戶是否有登錄,如果有權限則程序默認執(zhí)行,如果沒有權限控制程序流轉,不允許其訪問)
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方法專門用于攔截請求,可以做權限檢查
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//先獲取httpServletRequest對象,通過該對象獲取Session
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpSession session = httpServletRequest.getSession();
Object attribute = session.getAttribute("user");
//表示還沒有登陸
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標簽用于配置一個Filter過濾器 -->
<filter>
<!-- 配置Filter別名 -->
<filter-name>AdminFilter</filter-name>
<!-- 配置Filter全類名 -->
<filter-class>com.pero.servlet.AdminFilter</filter-class>
</filter>
<!-- 配置Filter過濾器的攔截路徑 -->
<filter-mapping>
<!-- 表示當前攔截路徑給哪一個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>登陸頁面</title>
</head>
<body>
<form action="http://localhost:8080/Filter_Web/loginServlet" method="get">
用戶名:<input type="text" name="username"><br/>
密碼:<input type="password" name="password"><br/>
<input type="submit" value="提交">
</form>
</body>
</html>Filter的生命周期
Filter的生命周期是指Filter從創(chuàng)建到銷毀整個過程執(zhí)行方法的順序。包含以下方法:
1.構造器方法;
2.init初始化方法;
3.doFilter過濾方法;
4.destory銷毀方法;
在Web工程啟動的時候構造器方法和初始化方法會被執(zhí)行(Filter對象已經(jīng)創(chuàng)建),每次攔截到請求時會執(zhí)行doFilter方法,停止Web工程的時候就會執(zhí)行destory方法。
FilterConfig類
FilterConfig類是Filter過濾器的配置文件類,Tomcat每次創(chuàng)建Filter的時候也會同時創(chuàng)建一個FilterConfig類,這里面包含了Filter配置文件的配置信息。
FilterConfig類的作用是獲取Filter過濾器的配置內容
1.獲取Filter的名稱filter-name的內容
2.獲取web.xml配置的init-param初始化參數(shù)
3.獲取ServletContext對象
package com.pero.servlet;
import jakarta.servlet.*;
import java.io.IOException;
public class TestFilter implements Filter {
public TestFilter() {
System.out.println("構造方法");
}
public void init(FilterConfig config) throws ServletException {
System.out.println("init初始化方法");
//獲取Filter的名稱filter-name的內容
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對象
ServletContext servletContext = config.getServletContext();
System.out.println("servletContext:" + servletContext);
}
public void destroy() {
System.out.println("destory銷毀方法");
}
@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標簽用于配置一個Filter過濾器 -->
<filter>
<!-- 配置Filter別名 -->
<filter-name>AdminFilter</filter-name>
<!-- 配置Filter全類名 -->
<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過濾器的攔截路徑 -->
<filter-mapping>
<!-- 表示當前攔截路徑給哪一個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過濾器鏈
客戶端(瀏覽器) -> 服務器(Filter①:執(zhí)行doFilter()方法:前置代碼1 ->chain.doFilter(request, response); -> Filter②:執(zhí)行doFilter()方法 :前置代碼1 -> chain.doFilter(request, response); -> 查詢目標資源,找到并獲取 -> 后置代碼2 ->Filter①:執(zhí)行doFilter()方法:后置代碼2)
FilterChain.doFilter()方法的作用:①如果有其他的Filter過濾器,執(zhí)行下一個Filter過濾器;②如果沒有其他需要執(zhí)行的過濾器,執(zhí)行目標資源。
多個Filter過濾器執(zhí)行的時候他們執(zhí)行的優(yōu)先順序是由在web.xml中filter-mapping從上到下的配置順序決定的。
多個Filter過濾器執(zhí)行的特點:
①所有Filter和目標資源默認都執(zhí)行在同一個線程中
②多個Filter共同執(zhí)行的時候,他們都使用同一個Request對象。
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頁面執(zhí)行");
System.out.println("目標資源"+Thread.currentThread().getName());
System.out.println("目標資源" + request.getParameter("username"));
%>
</body>
</html>Filter的攔截路徑
精確匹配
<url-pattern>/admin/*</url-pattern>
以上配置路徑表示請求地址必須為://ip:port/工程路徑/target.jsp
目標匹配
<url-pattern>/admin/*</url-pattern>
以上配置的路徑,表示請求地址必須為://ip:port/工程路徑/admin/*
后綴名匹配
<url-pattern>*.html</url-pattern>
以上配置路徑,表示請求地址必須為:.html
Filter過濾器只關心請求的值是否匹配,不關心資源是否存在
到此這篇關于JavaWeb中的Filter過濾器解讀的文章就介紹到這了,更多相關Filter過濾器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vscode開發(fā)maven的javaweb項目并部署到tomcat及配置指南
這篇文章主要給大家介紹了關于vscode開發(fā)maven的javaweb項目并部署到tomcat及配置的相關資料,在vscode中創(chuàng)建maven項目,需要逐一操作下面的環(huán)節(jié),文中通過圖文介紹的非常詳細,需要的朋友可以參考下2023-12-12
Java基礎之面向對象機制(多態(tài)、繼承)底層實現(xiàn)
這篇文章主要介紹了Java基礎之面向對象機制(多態(tài)、繼承)底層實現(xiàn),文中有非常詳細的代碼示例,對正在學習java的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04
IDEA中Maven報錯Cannot resolve xxx的解決方法匯總(親測有效)
在IDEA中的pom文件中添加了依賴,并且正確加載了相應依賴,pom文件沒有報紅,看起來像是把所有依賴庫全部加載進來了,但是代碼中使用依賴的類庫使報紅,本文給大家介紹了IDEA中Maven報錯Cannot resolve xxx的解決方法匯總,需要的朋友可以參考下2024-06-06
Java中BufferedReader和BufferedWriter使用方式
這篇文章主要介紹了Java中BufferedReader和BufferedWriter使用方式,F(xiàn)ileWriter?類從?OutputStreamWriter?類繼承而來,BufferedReader?類從字符輸入流中讀取文本并緩沖字符,以便有效地讀取字符,數(shù)組和行2022-06-06
PowerJob的GridFsManager工作流程源碼解讀
這篇文章主要為大家介紹了PowerJob的GridFsManager工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-01-01

