代码审计 | Java Web 过滤器 - filter
0x00 前言
filter 被称为过滤器,是 Servlet 2.3 新增的一个特性,同时也是 Serlvet 技术中最实用的技术。
过滤器实际上就是对 Web 资源进行拦截,做一些处理后再交给下一个过滤器或 Servlet 处理,通常都是用来拦截 request 进行处理的,也可以对返回的 response 进行拦截处理。
开发人员利用 filter 技术,可以实现对所有 Web 资源的管理,例如实现权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
0x01 filter 的配置
filter 的配置类似于 Servlet,由 filter 和 filter-mapping 两组标签组成,和 Servlet 一样,如果版本大于 3.0 也可以使用注解的方式来配置 filter
1、基于 web.xml 的配置
以下是一个基于 web.xml 的配置内容
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="2.5">
<display-name>manage</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>user</display-name>
<servlet-name>user</servlet-name>
<servlet-class>com.sec.servlet.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>user</servlet-name>
<url-pattern>/user</url-pattern>
</servlet-mapping>
<filter>
<display-name>test</display-name>
<filter-name>test</filter-name>
<filter-class>com.sec.test.test</filter-class>
</filter>
<filter-mapping>
<filter-name>test</filter-name>
<url-pattern>/test</url-pattern>
</filter-mapping>
</web-app>
标签含义如下:
<filter> 指定一个过滤器
<filter-name> 为过滤器指定一个名称,该项不能为空
<filter-class> 用于指定过滤器的完整的限定类名
<init-param> 用于为过滤器指定初始化参数
<param-name> 为 <init-param> 的子参数,用于指定参数的名称
<param-value> 为 <init-param> 的子参数,用于指定参数的值
<filter-mapping> 用于设置一个 filter 负责拦截的资源
<filer-name> 为 <filer-mapping> 的子参数,用于设置 filter 的注册名称,该值必须是在 <filter> 元素中声明过的过滤器的名称
<url-pattern> 用于设置 filter 所拦截的请求路径
<servlet-name> 用于指定过滤器所拦截的 Servlet 名称
2、基于注解的方法
示例代码如下
import java.io.IOException;
@WebFilter(description="this is filter test",urlPatterns={"/filterTest"})
public class filterTest implements Filter {
public void destroy() {
/*销毁时调用*/
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
/*过滤方法 主要是对request和response进行一些处理,然后交给下一个过滤器或Servlet处理*/
chain.doFilter(req, resp);//交给下一个过滤器或servlet处理
}
public void init(FilterConfig config) throws ServletException {
/*初始化方法 接收一个FilterConfig类型的参数 该参数是对Filter的一些配置*/
}
}
与 Servlet 一样,使用 web.xml 可以配置的 filter 属性也都可以使用注解进行配置,但一般不推荐使用注解配置,因为使用 web.xml 可以控制过滤器的执行顺序,而使用注解的方式则不行。
0x02 filter 的流程
filter 的流程很简单,具体如下:
用户向服务器发送请求
|
服务器
|
filter 1
|
......
|
filter n
|
service()方法
|
filter n
|
......
|
filter 1
|
服务器
|
服务器返回结果给用户
首先用户向服务器发起请求,之后请求经过过滤器到达 Servlet 中的 service() 方法,最后再经过过滤器返回给用户。
这里值得注意的是过滤器在接收请求和返回请求的时候顺序是相反的。
0x03 filter 的接口方法
filter 接口方法如下:
1、init() 接口
该接口与 Servlet 里的 init() 方法类似,主要用来初始化过滤器。如果初始化代码中要用到 FilterConfig 对象,那这些初始化代码只能在 filter 的 init() 方法中编写。
init() 方法的定义如下:
public void init(FilterConfig config) throws ServletException {
/*初始化方法 接收一个FilterConfig类型的参数 该参数是对Filter的一些配置*/
}
2、doFilter() 接口
doFilter 方法类似于 Servlet 接口的 service() 方法,filter 通过该接口实现具体的过滤操作,当客户请求访问与过滤器关联的 URL 的时候,Servlet 过滤器将先执行 doFilter 方法,FilterChain 参数用于访问后续过滤器。
doFilter() 方法定义如下:
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
/*过滤方法 主要是对request和response进行一些处理,然后交给下一个过滤器或Servlet处理*/
chain.doFilter(req, resp);//交给下一个过滤器或servlet处理
}
3、destroy() 接口
destroy() 接口和 servlet 里的 destroy() 作用类似,用于释放被 filter 打开的资源,如关闭数据库等。
destroy() 方法的定义如下:
public void destroy() {
/*销毁时调用*/
}
0x04 filter 的生命周期
filter 的生命周期与 servlet 的生命周期比较类似,如下图所示。
当 Web 容器启动时,会根据 web.xml 中声明的 filter 顺序依次实例化这些 filter。
这里会根据实际情况的不同,doFilter() 方法可能会被调用多次,最后当程序关闭或者卸载时调用 destroy() 方法。
往期推荐
参考文章: https://blog.csdn.net/Soinice/article/details/82787964 https://www.cnblogs.com/tanghaorong/p/12811457.html https://blog.csdn.net/yuzhiqiang_1993/article/details/81288912 原文链接: https://www.teamssix.com/211116-112510.html
相关文章
- Java爱心代码_java怎么敲入代码
- 二级java程序设计--Java SDK6.0的下载和操作[通俗易懂]
- java volatile关键字的作用_Java并发编程彻底搞懂volatile关键字「建议收藏」
- java queue toarray_Java PriorityBlockingQueue toArray()用法及代码示例
- fileinputstream java_Java FileInputStream close()方法
- java backoff_Java BackOff类代码示例
- 编写java判断闰年_用Java程序判断是否是闰年的简单实例[通俗易懂]
- java分前端后端吗_Java Web属于前端还是后端
- java启动器_JAVA基础:Java 启动器如何查找类
- java冒泡排序经典代码_Java 8大经典排序算法(含源代码),必须收藏!
- java后端开发需要学什么_从事Java后端开发,要学习哪些知识和技能?[通俗易懂]
- java dom4j 添加节点_Java dom4j获取,添加,删除,查找,设置Element节点方法「建议收藏」
- Java包装类
- Java 代码审计基础知识 — java反射机制
- 【愚公系列】2023年03月 Java教学课程 103-MySQL数据库(存储过程和函数)
- Java Web的web.xml文件作用及基本配置详解编程语言
- 实现使用Java代码实现MySQL数据库连接(java连接mysql数据库代码)
- 开启Java之门:访问MySQL数据库(java访问mysql数据库)
- 中的应用Java中MySQL的灵活运用(mysql在java代码)
- 学习如何使用Linux环境运行Java程序(linux下的java)
- Java联合Redis:建立良好数据连接(java连接redis)
- 面试前准备:Java技术和Redis快速入门(java面试redis)
- 如何在Linux系统下有效地启动Java程序,让你的代码在Linux中也能正常运行?(linux下启动java)
- Java技术封装Redis,打造高效数据处理系统(java封装redis)
- 深入学习:Linux下Java环境建设与配置(linux下java环境)
- 如何使用Java备份Oracle数据库?(java备份oracle)
- 展示Web与Oracle的极致结合(web oracle)
- Java使用Oracle实现优雅数据查询(java.oracle)