Filter可以视作是servlet的加强版,主要用作对用户的请求进行预处理,或者对返回给客户端的结果进行再次加工,是一个典型的链式处理模式。本篇简单介绍filter的基本使用方法,主要涉及以下内容:

Filter的背景知识

使用Filter的流程

Filter的生命周期

一个完整的实例

一、Filter的简单介绍

Filter在英文中是过滤器的意思,当然在此处的使用也是完美的切合了它的意思,我们使用filter的主要目的就是完成一个过滤的作用。可以在一个请求到达servlet之前,将其截取进行逻辑判断,然后决定是否放行到请求的servlet。也可以在一个response到达客户端之前,截取结果进行逻辑判断,然后决定是否允许返回给客户端。所以filter有如下几个种类:

用户授权的filter:filter负责判断用户是否有权限请求该页面,给予过滤判断

日志filter:截取某个用户在本网站上的所有请求,记录轨迹

负责解码的filter:规定处理本次请求的解码方式

最后需要注意的是,一个filter过滤器可以加在多个servlet控制器上,当然多个filter过滤器也是可以加在一个servlet控制器上的。由此也是可以看出来,我们使用filter往往是对一些公共的操作进行处理,例如:判断用户权限,解码本次请求等,还比如,我们的web应用中某些页面是需要用户登录后才能访问的,以往我们都是在每个servlet页面加上判断控制,导致代码冗余,有了filter,我们可以定义一个实现了filter的过滤器,让需要判断是否登录的页面都加上这么一个过滤器,可以大大降低代码的冗余程度。

二、Filter的使用流程

在Java中如果想要自定义一个filter过滤器的话,需要继承Javax.servlet.Filter接口,这个接口中只有三个方法:

default void init(FilterConfig filterConfig)

void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3)

default void destroy()

其中init和destroy方法是有默认实现的,也就是我们不是必须重写这两个方法,但是doFilter 这个方法是一个核心的方法,是我们必须要实现的。首先我们看init方法的作用,这个方法是用来初始化filter实例的,也就是当用户请求了某个拦截器而此拦截器又匹配了某个过滤器,此时web容器就会定位到该过滤器然后创建该filter类的实例对象并调用此实例的init方法,完成初始化工作。对于destroy方法毋庸置疑就是在过滤器执行结束的时候调用,主要完成对一些资源的释放。下面主要看dofilter这个方法。

doFilter方法是filter接口中的核心方法,一旦创建完该过滤器的实例之后,会执行dofilter方法,所有的过滤逻辑都是在此方法中进行的。主要有三个参数,第一个参数是一个ServletRequest对象,HttpServletRequest继承于此接口,当用户请求某个拦截器的时候,检测到此请求存在过滤器,于是会封装好本次请求的相关数据,传递给dofilter的ServletRequest参数,ServletResponse参数的来源和ServletRequest是一样的,都是由客户端封装过来的。至于第三个参数,这是一个FilterChain处理链,详细的介绍等说明了web.xml中配置filter之后。

第一步如上,创建一个继承自filter接口的类,并实现其中的三个方法。第二步是在web.xml中配置该类用于过滤哪些拦截器。web.xml代码如下:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"

version="3.1">

isLogin

Test_f.MyFilter

isLogin

/a

isLogin

/b

如上述的代码,我们需要两个操作,首先是定义一个filter,指定了该filter的name和相对应的过滤器类。然后我们可以通过filter-mapping映射过滤器和URL,此处使用了两个映射,对该过滤器指定了对路径名为/a和/b的请求进行拦截。当然这个url-pattern元素的值可以有以下三种形式,完全匹配(/a/b等),目录匹配(/* 、 /abc/等),扩展名(.a,*.b等)。

了解了配置filter的主要操作之后,我们回去看过滤器类,我们说init方法是在首次创建filter实例的时候,用于执行初始化操作的,其中有个参数FilterConfig ,这是当前filter的配置信息,其中方法如下:

String getFilterName();

ServletContext getServletContext();

String getInitParameter(String var1);

Enumeration getInitParameterNames();

其实在创建filter实例的时候,web容器会将此实例对应在web.xml中的配置信息读取并封装成一个FilterConfig 对象传递给init方法,getFilterName方法就是我们在web.xml中配置的filter-name,getServletContext会获取当前servlet的上下文,当我们在定义filter的时候使用来定义一些初始化参数的时候,就可以使用此方法来获取这些初始化参数。getInitParameterNames方法用于获取所有初始化参数的枚举集合。这样我们在init方法中就可以获取这些配置参数,初始化filter实例。

上面我们只定义了一个filter,如果我们对于一次请求需要执行多个filter,进行过滤操作的话,web容器会在你请求某个URL的时候,在web.xml中找到所有匹配的filter,按照注册的顺序以FilterChain 链的形式传递到方法doFilter的第三个参数中,而这个filterChain中只有一个方法:

void doFilter(ServletRequest var1, ServletResponse var2)

如果我们在 void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) 方法中调用var3.doFilter(var1,var2),就代表此filter实例结束,则web服务器会检查FilterChain对象中是否还有filter对象(因为这是一个链,filter的数量是大于等于一的),如果没有就会放行,直接调用目标地址,如果还有filter对象,就会转而执行下一个filter。正是由于这样的机制,我们才可以对于一个URL请求添加多个filter过滤器。

三、一个简单的实例

下面通过一个简单的实例直观的感受下filter过滤器的作用:

public class MyFilter implements Filter {

@Override

public void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException{

HttpServletRequest req = (HttpServletRequest)var1;

HttpSession session = req.getSession();

String state = (String)session.getAttribute("state");

if(state.equals("1")){

var3.doFilter(var1,var2);

}else{

HttpServletResponse response = (HttpServletResponse)var2;

response.sendRedirect("Error_page.html");

}

}

}

//web.xml

isLogin

Test_f.MyFilter

isLogin

/index.jsp

这是index页面

//set.jsp

//为了使程序简单,我们采用手动设置session

//在实际的项目中,当用户登录之后自动设置session

我们首先访问set.jsp页面设置本次会话的session值,然后修改浏览器地址栏访问index.jsp页面

敲下回车键,结果如下:

我们先看,敲下回车键之后,程序怎么执行的,因为我们在web.xml中配置了MyFilter的拦截URL为index.jsp,所以当我们访问index.jsp的时候,会创建MyFilter 实例对象,封装配置信息到FilterConfig对象中,然后封装request请求和response,还有从web.xml 中读取的FilterChain对象传入MyFilter的doFilter方法中,我们在其中获取本次会话的session对象,取得其中的数据,如果为一放行,否则跳转到错误页面。此处的state的session值为0,我们在set.jsp中设置的,大家也可以在set.jsp页面设置其值为1,这样最终的结果会是这样的:

上述的demo只是为了简单的演示,其实使用filter可以完成大大的降低我们的代码的冗余程度。这个例子是为了演示,所以很简单。

四、Filter 的生命周期

当用户请求某个页面时候,会到web.xml中匹配是否存在能够匹配上此次请求的filter,如果有封装它的配置信息,FilterChain链。然后调用init方法,完成初始化,接着调用dofilter方法,处理核心逻辑,当此实例被销毁的时候,会调用destroy方法。

本篇文章结束,如果有理解错误,望大家指出!

java过滤器定义_Java ---Filter过滤器相关推荐

  1. java过滤器的执行顺序_Java Filter过滤器(拦截路径的配置+拦截方式的配置+生命周期+多个过滤器的先后执行顺序)...

    Java Filter过滤器+Listen监听器 啥是过滤器 顾名思义即过滤掉一些东西,比如我们经历的高考中考都是过滤器,他过滤掉一些在学习这一方面不是很好的人,而那些成绩好的人则升入高中,大学. 但 ...

  2. java filter过滤器_JavaWeb之 Filter(过滤器)

    FIlter作用 过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的. 当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如 ...

  3. servlet过滤器 实例_Java Servlet过滤器示例教程

    servlet过滤器 实例 Java Servlet Filter is used to intercept the client request and do some pre-processing ...

  4. filter过滤器_JavaWeb之 Filter(过滤器)

    FIlter作用 过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的. 当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如 ...

  5. java stream过滤_Java Stream过滤器

    java stream过滤 Java Stream filter can be very helpful when you want to do some processing only on som ...

  6. java straem 过滤_Java Stream 过滤器

    Java Stream 过滤器教程展示了如何使用过滤操作过滤 Java 流. Java 流 Java 流是来自源的支持聚合操作的一系列元素. 流不存储元素. 元素是按需计算的. 元素是从数据源(如集合 ...

  7. jsp过滤器示例_Java 8过滤器,地图,收集和流示例

    jsp过滤器示例 大家好,许多读者给我发了电子邮件,写了一篇有关Java 8的地图和过滤器功能的文章,因为他们发现它们难以理解和使用. 即使我以前同时写过有关map()和filter()的博客,我仍在 ...

  8. java 类定义_JAVA类与对象(二)----类定义基础

    类是组成java程序的基本要素,是java中的一种重要的复合数据类型.它封装了一类对象的状态和方法,是这一类对象的原型.一个类的实现包括两个部分:类声明和类体,基本格式: class { 属性 方法 ...

  9. java final定义_Java中final关键字的用法

    final在Java中并不常用,然而它却为我们提供了诸如在C语言中定义常量的功能,不仅如此,final还可以让你控制你的成员.方法或者是一个类是否可被覆写或继承等功能,这些特点使final在Java中 ...

  10. java字符串定义_java字符串基本概念

    java字符串基本概念 那随意了 • 2020 年 02 月 23 日 字符串字符串本质是一个char类型的数组 private final char value[] //底层的实现代码 不可变字符串 ...

最新文章

  1. 自定义定时器的一点总结
  2. js页面传值(注意中文)
  3. 趣话题:git三部曲(二)-拆分历史提交记录reset
  4. 工作277:v-model实战
  5. 信息服务器为什么选择在贵州,为啥云服务器在贵州
  6. 实践线性模型对于大规模一类别协同过滤
  7. Eclipse报错:this compilation unit is not on the build path of a java project
  8. python输入一个序列_Python序列合并,python
  9. java移位运算_Java移位运算符 “
  10. Pattern Recognition and Machine Learning(模式识别与机器学习)第一章导读
  11. UNet 、3D-UNet 、VNet 区别
  12. 百度指数python爬虫的简单应用
  13. codeblock-(no debugging symbols found)(已解决)
  14. Kali linux渗透测试系列————29、Kali linux 渗透攻击之无线网络攻击
  15. 现在都在考华为认证,含金量高不高呢?该如何备考?
  16. 有一架天平12个小球,其中有11个重量相同,1个与另外11个不同(不清楚这个球是轻还是重),要求最多称3次,就可以将其中重量特殊的小球找出来。
  17. 服务器常见状态码以及对应关系
  18. Nginx无法启动 遇见unknown directive if(!-f in E:\xiangmu\nginx-1.14.0/conf/nginx.conf:28
  19. 基于路灯控制系统的线缆防盗方案
  20. c语言mac地址字符串转换成数组,CString类型的MAC地址转换为数组类型

热门文章

  1. 答复: 关于用异常控制程序流程的看法
  2. 智能制造与大数据平台
  3. svn多分支开发合并技巧(idea or tortoiseSVN)
  4. oracle中imp命令详解,Oracle中imp命令详解
  5. 二十分钟精通排版神器Markdown,从此word和秀米是路人
  6. msm 8953 camera 流程
  7. Python 救救我!如何连接串口实现一个报警灯报警器
  8. Python之GUI编程 实现界面化的词云图生成器.exe
  9. xlsxwriter去掉网格线_python之xlsxwriter模块(可操作xls/xlsx格式文件)
  10. VINS-Mono 代码详细解读——视觉跟踪 feature_trackers