JavaWeb中的Filter过滤器解读

 更新时间:2023年10月17日 09:06:42   作者:Neo丶  
这篇文章主要介绍了JavaWeb中的Filter过滤器解读,Filter过滤器是JavaWeb的三大组件之一,Filter过滤器是JavaEE的规范也就是接口,Filter的作用是拦截请求,过滤响应,需要的朋友可以参考下

Filter过滤器

Filter过滤器是JavaWeb的三大组件之一,Filter过滤器是JavaEE的规范也就是接口,Filter的作用是拦截请求,过滤响应。

拦截请求常见的应用场景:权限检查、日志操作、事务管理等等。

Filter过滤器的基本使用

例如权限检查,若没有成功验证用户信息无法打开目标页面。

<%
    Object user = session.getAttribute("user");
    if (user == null){
        request.getRequestDispatcher("/login.jsp").forward(request,response);
        return;
    }
%>

用户登录后会将用户登陆信息保存到Session域中,所以要检查用户是否登录,判断Session中是否包含用户登录信息。

客户端(浏览器) -> Filter过滤器(进行权限检查,检查用户是否有登录,如果有权限则程序默认执行,如果没有权限控制程序流转,不允许其访问)

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 {
            //程序继续向下执行
            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从创建到销毁整个过程执行方法的顺序。包含以下方法:

1.构造器方法;

2.init初始化方法;

3.doFilter过滤方法;

4.destory销毁方法;

在Web工程启动的时候构造器方法和初始化方法会被执行(Filter对象已经创建),每次拦截到请求时会执行doFilter方法,停止Web工程的时候就会执行destory方法。

FilterConfig类

FilterConfig类是Filter过滤器的配置文件类,Tomcat每次创建Filter的时候也会同时创建一个FilterConfig类,这里面包含了Filter配置文件的配置信息。

FilterConfig类的作用是获取Filter过滤器的配置内容

1.获取Filter的名称filter-name的内容

2.获取web.xml配置的init-param初始化参数

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初始化参数
        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①:执行doFilter()方法:前置代码1 ->chain.doFilter(request, response); -> Filter②:执行doFilter()方法 :前置代码1 -> chain.doFilter(request, response); -> 查询目标资源,找到并获取 -> 后置代码2 ->Filter①:执行doFilter()方法:后置代码2)

FilterChain.doFilter()方法的作用:①如果有其他的Filter过滤器,执行下一个Filter过滤器;②如果没有其他需要执行的过滤器,执行目标资源。

多个Filter过滤器执行的时候他们执行的优先顺序是由在web.xml中filter-mapping从上到下的配置顺序决定的。

多个Filter过滤器执行的特点:

①所有Filter和目标资源默认都执行在同一个线程中

②多个Filter共同执行的时候,他们都使用同一个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页面执行");
        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过滤器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java使用EasyExcel进行单元格合并的问题详解

    Java使用EasyExcel进行单元格合并的问题详解

    项目中需要导出并合并指定的单元格,下面这篇文章主要给大家介绍了关于java评论、回复功能设计与实现的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • vscode开发maven的javaweb项目并部署到tomcat及配置指南

    vscode开发maven的javaweb项目并部署到tomcat及配置指南

    这篇文章主要给大家介绍了关于vscode开发maven的javaweb项目并部署到tomcat及配置的相关资料,在vscode中创建maven项目,需要逐一操作下面的环节,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • Java基础之面向对象机制(多态、继承)底层实现

    Java基础之面向对象机制(多态、继承)底层实现

    这篇文章主要介绍了Java基础之面向对象机制(多态、继承)底层实现,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-04-04
  • springboot实现异步任务

    springboot实现异步任务

    这篇文章主要为大家详细介绍了springboot实现异步任务,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-05-05
  • Java文件与IO流操作原理详细分析

    Java文件与IO流操作原理详细分析

    在java中提供有对于文件操作系统的支持,这个支持在java.io.File类中进行了定义,也就是说在整个java.io包中File类是唯一一个与文件本身操作有关的类(创建,删除,重命名)有关的类,而如果想要进行File类的操作,我们需要提供有完整的路径支持,而后可以调用相应的方法进行处理
    2022-09-09
  • IDEA中Maven报错Cannot resolve xxx的解决方法汇总(亲测有效)

    IDEA中Maven报错Cannot resolve xxx的解决方法汇总(亲测有效)

    在IDEA中的pom文件中添加了依赖,并且正确加载了相应依赖,pom文件没有报红,看起来像是把所有依赖库全部加载进来了,但是代码中使用依赖的类库使报红,本文给大家介绍了IDEA中Maven报错Cannot resolve xxx的解决方法汇总,需要的朋友可以参考下
    2024-06-06
  • java中将一个实体类复制到另一个实体类的3种方法示例

    java中将一个实体类复制到另一个实体类的3种方法示例

    这篇文章主要给大家介绍了关于java中将一个实体类复制到另一个实体类的3种方法,所谓实体类就是一个拥有Set和Get方法的类,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-07-07
  • Java中BufferedReader和BufferedWriter使用方式

    Java中BufferedReader和BufferedWriter使用方式

    这篇文章主要介绍了Java中BufferedReader和BufferedWriter使用方式,FileWriter 类从 OutputStreamWriter 类继承而来,BufferedReader 类从字符输入流中读取文本并缓冲字符,以便有效地读取字符,数组和行
    2022-06-06
  • java中Ajax与Axios的使用小结

    java中Ajax与Axios的使用小结

    在项目中我们经常会遇到需要向请求头中添加消息的场景,本文主要介绍了java中Ajax与Axios的使用小结,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2024-02-02
  • PowerJob的GridFsManager工作流程源码解读

    PowerJob的GridFsManager工作流程源码解读

    这篇文章主要为大家介绍了PowerJob的GridFsManager工作流程源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01

最新评论