JavaWeb开发Filter学习

博主信息:

📢@博主: 嘟嘟的程序员铲屎官
💬:一位爱喵咪,爱开源,爱总结,爱分享技术的Java领域新星博主,如果你想和博主做朋友,关注博主,并私聊博主(给我发一条消息我就会关注你喔),博主本人也十分喜欢解决问题,如果你有什么问题,也可以来私聊博主喔,希望能够和C站的朋友相互学习,相互进步。
💬:关于本篇博客,最近在看廖雪峰大佬JavaWeb部分的知识,对大佬的使用Filter这一篇进行个人总结,如果有什么错误的,请各位大佬能够及时提出,以免小弟误人子弟!

一.使用Filter

1.Filter

为了把一些公用逻辑从各个Servlet中抽离出来,JavaEE的Servlet规范还提供了一种Filter组件,即过滤器,它的作用是,在HTTP请求到达Servlet之前,可以被一个或多个Filter预处理,类似打印日志、登录检查等逻辑,完全可以放到Filter中。

2.Filter处理方式

Filter的处理方式如下图:

  • 客户端的请求会经过过滤器,然后到达目标资源进行处理,目标资源处理之后再经过过滤器最后响应给客户端。

在这里插入图片描述

多个Filter组成一条Filter链如下图:

  • 在第1个过滤器处理一个请求后,会传递给第2个过滤器处理,直到最后一个过滤器将请求交给目标资源处理。目标资源在处理经过过滤的请求后,其响应信息从最后一个过滤器依次传递到第1个过滤器,最后传送到客户端。

在这里插入图片描述

3.Filter的核心对象

下面通过2个操作,来理解Filter的核心对象:
操作1:
在Tomcat中lib目录下,将servlet-api.jar 拷贝到任意一个文件下并进行解压
在这里插入图片描述
会生成如下二个文件:

  • javax:源码文件
  • META-INF文件:用于存储包和扩展的配置数据,如安全性和版本信息

在这里插入图片描述
进入..\javax\servlet
在这里插入图片描述
从上面的操作我们可知:

Filter位于javax.servlet包下, Filter相关的几个.class文件如下:

  • Filter.class
  • FilterChain.class
  • FilterConfig.class
  • FilterRegistration$Dynamic.class
  • FilterRegistration.class

操作2:

通过jad将.class反编译为.java文件

相关资料:
jad:jad.exe(java反编译工具)32/64位
教程: 如何将class文件转换成java文件

操作非常简单,windows+R输入cmd,进入dos按照下图所示进行操作即可
我的jad目录如下:
在这里插入图片描述

在这里插入图片描述
进入到反编译存放文件中,我们会发现Filter相关的.java只有如下四个:

  • Filter.java
  • FilterChain.java
  • FilterConfig.java
  • FilterRegistration.java
    在这里插入图片描述

打开Filter.java,对该类进行分析
在这里插入图片描述

从上面的源码可知:
Filter是一个接口,该接口有如下三个抽象方法(方法的解释来源于<<JavaWeb入门经典>>这本书):

Filter接口抽象方法方法解释
init(FilterConfig filterconfig)过滤器初始化方法,此方法在初始化过滤器时调用
doFilter(ServletRequest servletrequest, ServletResponse servletresponse, FilterChain filterchain)对请求进行过滤处理
destroy();销毁方法以释放资源

打开FilterConfig.java,对该类进行分析
在这里插入图片描述
从上面的源码可知:
FilterConfig是一个接口,用于配置Filter,该接口有如下四个抽象方法(方法的解释来源于<<JavaWeb入门经典>>这本书)

FilterConfig接口抽象方法方法解释
getFilterName();用于获取过滤器名
getServletContext();获取Servlet上下文
getInitParameter(String s);获取过滤器的初始化参数值
getInitParameterNames();获取过滤器的所有初始化参数

FilterConfig的配置可通过标签的方式进行配置:

@WebFilter(urlPatterns={"/index","/sign"})

该标签对访问/index/sign路径的请求将经过该过滤器,注意urlPatterns={"/*"}标识对所有请求都要经过该过滤器。

FilterConfig的配置可通过web.xml的方式进行配置(和Servlet类似):
在这里插入图片描述
如果多个过滤器应用于同一个资源,那么调用顺序就很重要,必须用部署描述符管理应该先调用哪一个过滤器。假如Filter1必须在Filter2之前调用,那么在部署描述符中,Filter1的声明就要放在 Filter2的声明之前。
在这里插入图片描述

打开FilterChain.java文件,对该类进行分析
在这里插入图片描述
从上面的源码可知:
FilterChain是一个接口,该接口只有如下一个抽象方法

   public abstract void doFilter(ServletRequest servletrequest, ServletResponse servletresponse)
        throws IOException, ServletException;

此方法用于将过滤后的请求传递给下一个过滤器,如果此过滤器是过滤器链中的最后一个过滤器,那么请求将传送给目标资源。

打开FilterRegistration.java,对该类进行分析
在这里插入图片描述
从上面的源码可知:
FilterRegistration是一个接口,接口中有一个嵌套接口和4个抽象方法
嵌套接口:

public static interface Dynamic extends FilterRegistration,Registration.Dynamic
{
}

通过该接口可以进一步配置Filter,通过ServletContext上的addFilter方法注册Filter。

4个抽象方法:

FilterRegistration接口抽象方法方法解释
addMappingForServletNames(EnumSet enumset, boolean flag, String as[]);通过ServletNames添加的映射
getServletNameMappings();获取Servlet映射名称集合
addMappingForUrlPatterns(EnumSet enumset, boolean flag, String as[]);通过UrlPatterns添加映射
getUrlPatternMappings();获取当前可用URL模式映射。

总结: 从上面的分析我们可以知道,Filter是一个接口,该接口下有三个抽象方法init()用于初始化Filter,doFilter()用于处理过滤的业务逻辑,destroy()用于销毁Filter,然后就是与Filter相关的二个接口,FilterConfig接口用于Filter的配置,FilterChain接口用于对Filter链进行管理,通过doFilter()方法将请求向下传递给下一个过滤器或目标资源,另外还有一个FilterRegistration接口用于对Filter进一步进行配置。

4.Filter例子(字符编码过滤器)

在前面我们每编写一个Servlet都会在相应的doGet()/doPost()方法中写如下代码用于避免出现乱码,显然该代码是一个公用的代码,对于这种代码我们可以将它放到Filter中的doFilter()中进行处理,这样就避免了重复编写此代码。
在这里插入图片描述

项目结构:
在这里插入图片描述
IndexServlet.java
在这里插入图片描述

SignInServlet.java
在这里插入图片描述

index.html
在这里插入图片描述
运行效果:
在这里插入图片描述
点击跳转到IndexServlet
在这里插入图片描述
点击跳转到SignServlet
在这里插入图片描述
解决方法:
在该项目中创建一个filter的包,在该包下创建一个EncodingFilter.java类该类实现Filter接口,并重写该接口的三个抽象方法,通过@WebFilter标签初始化FilterConfig,再将IndexServlet和SignInServlet的公用代码移到该类的doFilter()中,然后通过FilterChain.doFilter()方法传递到下一个Filter或目标资源。
在这里插入图片描述
再次运行效果一致,但是Servlet中少了公用代码:
IndexServlet.java
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘟嘟的程序员铲屎官

你的鼓励将是我最大的动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值