JavaWeb开发Filter学习

简介: JavaWeb开发Filter学习

博主信息:

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

@Toc

一.使用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
在这里插入图片描述
在这里插入图片描述

相关文章
|
4天前
|
人工智能 自然语言处理 Java
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
文章介绍了Spring AI,这是Spring团队开发的新组件,旨在为Java开发者提供易于集成的人工智能API,包括机器学习、自然语言处理和图像识别等功能,并通过实际代码示例展示了如何快速集成和使用这些AI技术。
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
|
4天前
|
前端开发 Java 编译器
【前端学java】如何从前端视角快速学习Maven
【8月更文挑战第12天】如何从前端视角快速学习Maven
12 2
【前端学java】如何从前端视角快速学习Maven
|
1天前
|
数据采集 供应链 JavaScript
分享基于Java开发的Java毕业设计实战项目题目
这篇文章分享了67套基于Java开发的毕业设计实战项目题目,覆盖了互联网、企业管理、电子政务、Java基础项目、ERP系统、校园相关、医疗以及其他细分行业等多个领域,并推荐了使用IDEA、Vue和Springboot的技术栈。
|
1天前
|
分布式计算 Java API
Java 8带来了流处理与函数式编程等新特性,极大提升了开发效率
Java 8带来了流处理与函数式编程等新特性,极大提升了开发效率。流处理采用声明式编程模型,通过filter、map等操作简化数据集处理,提高代码可读性。Lambda表达式支持轻量级函数定义,配合Predicate、Function等接口,使函数式编程无缝融入Java。此外,Optional类及新日期时间API等增强功能,让开发者能更优雅地处理潜在错误,编写出更健壮的应用程序。
6 1
|
6天前
|
SQL 存储 Java
完整java开发中JDBC连接数据库代码和步骤
该博客文章详细介绍了使用JDBC连接数据库的完整步骤,包括加载JDBC驱动、提供连接URL、创建数据库连接、执行SQL语句、处理结果以及关闭JDBC对象的过程,并提供了相应的示例代码。
|
1天前
|
人工智能 网络协议 Java
23.12月中旬 上海寻序人工智能科技-上海嘉定-Java开发实习生-薪资150-230/d 面经
关于上海寻序人工智能科技有限公司Java开发实习生岗位的面试经验分享,涵盖了技术问题如对象存储MinIO、ArrayList扩容、Object类方法、hashCode和equals方法、处理哈希冲突、JVM垃圾回收器、GC算法、网络协议、邮件协议、HTTP请求方法、Linux和Docker命令、Dockerfile制作等。
3 0
|
5天前
|
SQL 存储 Java
完整java开发中JDBC连接数据库代码和步骤
该博客文章详细介绍了使用JDBC连接数据库的完整步骤,包括加载JDBC驱动、提供连接URL、创建数据库连接、执行SQL语句、处理结果以及关闭JDBC对象的过程,并提供了相应的示例代码。
|
7天前
|
Java 开发者
奇迹时刻!探索 Java 多线程的奇幻之旅:Thread 类和 Runnable 接口的惊人对决
【8月更文挑战第13天】Java的多线程特性能显著提升程序性能与响应性。本文通过示例代码详细解析了两种核心实现方式:Thread类与Runnable接口。Thread类适用于简单场景,直接定义线程行为;Runnable接口则更适合复杂的项目结构,尤其在需要继承其他类时,能保持代码的清晰与模块化。理解两者差异有助于开发者在实际应用中做出合理选择,构建高效稳定的多线程程序。
28 7
|
6天前
|
安全 Java 数据库
一天十道Java面试题----第四天(线程池复用的原理------>spring事务的实现方式原理以及隔离级别)
这篇文章是关于Java面试题的笔记,涵盖了线程池复用原理、Spring框架基础、AOP和IOC概念、Bean生命周期和作用域、单例Bean的线程安全性、Spring中使用的设计模式、以及Spring事务的实现方式和隔离级别等知识点。
|
6天前
|
存储 监控 安全
一天十道Java面试题----第三天(对线程安全的理解------>线程池中阻塞队列的作用)
这篇文章是Java面试第三天的笔记,讨论了线程安全、Thread与Runnable的区别、守护线程、ThreadLocal原理及内存泄漏问题、并发并行串行的概念、并发三大特性、线程池的使用原因和解释、线程池处理流程,以及线程池中阻塞队列的作用和设计考虑。