JavaWeb过滤器(Filter)详解,是时候该把过滤器彻底搞懂了(万字说明)

  • 第一部分代码会对游览器请求进行第一次过滤,然后继续执行

  • 第二部分代码就是将游览器请求放行,如果还有过滤器,那么就继续交给下一个过滤器

  • 第三部分代码就是对返回的Web资源再次进行过滤处理

我们使用过滤器,也就是说,不止请求会经过过滤器,我们的响应也会经过过滤器。


过滤器(Filter)接口


我们学习过滤器,肯定就要先看一下官方给我们提供的过滤器接口。下面我们使用Idea来查看Filter。

我们通过官方提供的过滤器可以看出过滤器(Filter)使用起来还是比较简单的,下面我们就来学习如何使用过滤器(Filter)


使用过滤器(Filter)

=============

我们使用过滤器肯定要导入相应的jar包才行,Filter就在servlet-api.jar中,我们将该jar包放到WEB-INF下的lib目录下面,然后加入项目。

创建过滤器(Fliter)


我们创建Filter,只需要继承Filter接口就行。

import javax.servlet.*;

import java.io.IOException;

public class MyFilter implements Filter {

@Override

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

}

}

Filter接口有3个方法,但是只有一个方法没有实现,我们只需要实现这个方法就行。我们可以发现,我们实现了一个doFilter方法,这个方法就是我们写过滤代码的地方,具体逻辑就是和上面介绍的过滤器原理一样的。


使用过滤器(Filter)


我们先来感受一下如何使用过滤器,细节我们后面慢慢说明。我们在上面创建的类中写入以下代码,并且加一个WebFIlter注解

import javax.servlet.*;

import javax.servlet.annotation.WebFilter;

import java.io.IOException;

@WebFilter(“/*”)

public class MyFilter implements Filter {

@Override

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

System.out.println(“对request进行过滤”);

//下面这行代码就是放行

filterChain.doFilter(servletRequest,servletResponse);

System.out.println(“对response进行过滤”);

}

}

我简单介绍下上面的代码,WebFilter(“/*”)表示对所有请求进行过滤,而在doFilter中的放行代码,也就是filterChain.doFilter(servletRequest,servletResponse);这行代码就是对拦截进行放行,细节我们后面讲,现在先怎么理解就行。

启动服务器,然后我们在游览器中输入http://localhost:8080/filter/abc,注意,filter是我们自己配置的web工程路径,后面的abc随便输入的。我们下面来查看游览器后控制台输出。

游览器输出

控制台输出

现在,我们就已经可以得出两个结论了,过滤器并不会管资源是否存在,而只会对配置的拦截路径进行拦截。拦截不仅会对请求进行拦截,而且还会对相应进行拦截。


配置过滤器(Filter)拦截路径


配置Filter的拦截路径有2种方式,一种是注解,一种是xml方式,我们分别进行讲解。

注解方式

我们如果使用注解来进行配置,那么我们就需要使用@WebFilter,我们不说废话,直接看该注解的源码。

里面的配置项还是有很多的,下面我对常用配置项进行说明:

  • filterName:该filter的名字

  • initParams:初始化参数

  • displayName:filter显示名称

  • servletNames:指定对哪些servlet进行过滤

  • asyncSupported:是否支持异步模式

  • urlPatterns:指定拦截路径

  • value:指定拦截路径

注意:urlPatterns和value是一样的。urlPatterns和value只能配置一个,不能两个都配置,两个都配置就会报错。

对于使用**@WebFilter**,里面的多个参数用 , 进行分隔。

说明:如果我们仅仅需要配置一个拦截路径,那么我们可以直接简写@WebLister(“拦截路径”),如@WebFilter(“/*”)就是拦截所有请求。


xml方式

xml方式可以说是和Servlet使用xml配置方式一样了,这里就不废话,直接配置一个。

myFilter

com.clucky.filter.MyFilter

myFilter

/*

这个就是xml配置方式,只不过把注解换成了xml标签来配置,里面属性都是一样的,这个和Servlet的配置方式基本一样,这里就不再赘述了。


过滤器(Filter)生命周期


我们都知道Servlet有一个生命周期,当然Filter也有一个生命周期,下面我们就来探讨一下Filter的生命周期。

Filter的生命周期和Servlet也十分相似,如果大家对Servlet的生命周期不怎么熟悉,那么可以看一下这篇文章Servlet生命周期

我们创建一个类,实现Filter的所有方法。

import javax.servlet.*;

import java.io.IOException;

public class LifeCycleFilter 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有3个阶段,分别是初始化,拦截和过滤,销毁。

  1. 初始化阶段:当服务器启动时,我们的服务器(Tomcat)就会读取配置文件,扫描注解,然后来创建我们的Filter。

  2. 拦截和过滤阶段:只要请求资源的路径和拦截的路径相同,那么过滤器就会对请求进行过滤,这个阶段在服务器运行过程中会一直循环。

  3. 销毁阶段:当服务器(Tomcat)关闭时,服务器创建的Filter也会随之销毁。


代码演示

Filter的三个阶段就对应着Filter的3个方法,init方法会在Filter创建时调用,doFilter方法会在请求和拦截匹配时调用,destroy方法会在Filter销毁时调用。我们来对这些方法进行编写验证。

import javax.servlet.*;

import javax.servlet.annotation.WebFilter;

import java.io.IOException;

@WebFilter(“/*”)

public class LifeCycleFilter implements Filter {

@Override

public void init(FilterConfig filterConfig) throws ServletException {

//这个方法就是初始化方法,在Filter创建时调用

System.out.println(“调用了init()方法”);

}

@Override

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

//这个方法就是过滤和拦截的方法,当请求和拦截匹配时调用

System.out.println(“调用了doFilter()方法”);

}

@Override

public void destroy() {

//这个方法就是销毁方法,在Filter销毁前调用

System.out.println(“调用了destroy()方法”);

}

}

启动服务器控制台输出

进行拦截时控制台输出

关闭服务器控制台输出

都和我们预想的一样,到此,我们就成功验证了Filter的生命周期。


FilterConfig和FilterChain说明

===========================

FilterConfig和FilterConfig这2个对象是由服务器(Tomcat)在创建和调用Filter对象时所传入的,这2个对象十分有用,FilterConfig对象可以读取我们配置的初始参数,FilterChain可以实现多个Filter之间的连接。


FilterConfig


老规矩,我们要学习一个对象,首先查看类图和源代码

里面的方法就4个,下面我们分别进行讲解

  • getFilterName():获取filter的名称

  • getServletContext():获取ServletContext

  • getInitparamter(String var1):获取配置的初始参数的值

  • getInitParamterNames():获取配置的所有参数名称


FilterConfig实例运用

我们在init方法中使用FilterConfig来读取配置的数据库的信息,然后输出。

java代码

import javax.servlet.*;

import java.io.IOException;

import java.util.Enumeration;

public class MyFilterConfig implements Filter {

@Override

public void init(FilterConfig filterConfig) throws ServletException {

System.out.println(“-----------获取全部key:value------------”);

//得到所有配置参数的名字

Enumeration names = filterConfig.getInitParameterNames();

while (names.hasMoreElements()) {

//得到每一个名字

String name = names.nextElement();

System.out.println(name+" = "+filterConfig.getInitParameter(name));

}

System.out.println(“-----------end…------------”);

}

@Override

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

}

@Override

public void destroy() {

}

}

xml配置

myFilterConfig

com.clucky.filter.MyFilterConfig

driver

com.mysql.jdbc.Driver

url

jdbc:mysql://localhost:3306/equip_employ_manage?serverTimezone=GMT

username

root

password

root

myFilterConfig

/*

启动服务器,控制台输出

我们使用FilterConfig提供的方法就成功实现了功能,FilterConfig就是用来读取配置文件的。


FilterChain


一样,我们还是先来查看源代码以及类图

我们查看类图,可以发现FilterChain就只有一个方法,其实这个方法就是用来对拦截进行放行的,如果有多个拦截器,那么就会继续调用下一个Filter进行拦截。doFilter方法需要传入个参数,一个是ServletRequest,一个是ServletResponse参数,这个直接传入进行。

Tomcat在调用过滤器时,默认就会传入Request和Response,这个参数封装了请求和响应,我们直接使用就行。ServletResquest和ServletResponse可以直接强转成HttpServletRequest和HttpServletResponse,然后使用相应的方法。

将ServletRequest转成HttpServletRequest


FilterChain应用实例

我们前面一直都是一个Filter,现在我们来配置2个Filter,通过FilterChain来进行多个过滤。

第一个Filter

import javax.servlet.*;

import javax.servlet.annotation.WebFilter;

import java.io.IOException;

@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 {

System.out.println(“调用过滤器01对请求进行过滤~~~~”);

//放行,如果还有过滤器,那么就执行下一个过滤器

filterChain.doFilter(servletRequest,servletResponse);

System.out.println(“调用过滤器01对响应进行过滤~~~~”);

}

@Override

public void destroy() {

}

}

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

最后

每年转战互联网行业的人很多,说白了也是冲着高薪去的,不管你是即将步入这个行业还是想转行,学习是必不可少的。作为一个Java开发,学习成了日常生活的一部分,不学习你就会被这个行业淘汰,这也是这个行业残酷的现实。

如果你对Java感兴趣,想要转行改变自己,那就要趁着机遇行动起来。或许,这份限量版的Java零基础宝典能够对你有所帮助。

Override

public void destroy() {

}

}

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-0X3nqUy4-1711138339846)]
[外链图片转存中…(img-vkyUMbSb-1711138339847)]
[外链图片转存中…(img-Xi1z2TZr-1711138339848)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-EkJhwXa3-1711138339848)]

最后

每年转战互联网行业的人很多,说白了也是冲着高薪去的,不管你是即将步入这个行业还是想转行,学习是必不可少的。作为一个Java开发,学习成了日常生活的一部分,不学习你就会被这个行业淘汰,这也是这个行业残酷的现实。

如果你对Java感兴趣,想要转行改变自己,那就要趁着机遇行动起来。或许,这份限量版的Java零基础宝典能够对你有所帮助。

[外链图片转存中…(img-d6CffyJa-1711138339849)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值