时间:2021-05-20
Filter过滤器技术。通过过滤器,可以对来自客户端的请求进行拦截,进行预处理或者对最终响应给客户端的数据进行处理后再输出。
要想使用Filter过滤器,非常简单,只要实现Servlet API中的Filter接口即可,同时在该web应用【WEB-INF】目录下的web.xml文件中配置<filter>和<filter-mapping>两个标签。其中可以根据配置指定过滤的页面或者Servlet。
也就是说我们在web工程中光光写Filter过滤器的Java代码是不会起作用的,要在web.xml文件中对过滤器进行注册和映射,在学习Filter之前我们先来学习如何注册和映射
关于注册:
需要在web.xml文件中配置<filter>标签,这还不够,<filter>标签下的<filter-name>与<filter-class>是必须要填的内容。
<filter>标签中有如下子元素:
关于映射:
需要在web.xml文件中配置<filter-mapping>标签,这还不够,<filter-mapping>标签下的<filter-name>以及<url-pattern>或<servlet-name>之一是必须的。
<filter-mapping>标签中有如下子元素:
关于<dispathcer>的四种方式,这里再简单的介绍一下:
一个简单的对过滤器的注册和映射的示例:
在Servlet API 中关于Filter举例了使用过滤器能用来做些什么:
这里我也说明下平时Filter能在哪些方面会被经常用到:
① Filter可以作用在请求资源执行之前,进行权限检查,检查用户是否有权限,如有权限则放行请求;如果没有,则拒绝访问。
② Filter可以作用在请求资源执行之前,对Request和Response对象进行预处理操作,从而实现一些web应用的全局性设置,比如解决中文乱码问题。
③ Filter可以作用在最终响应输出之前,对输出Response对象中的数据进行处理,例如将输出的数据进行压缩。
Filter只有3个方法:
其中destroy()方法和init(…)方法是生命周期方法,因为过滤器无论如何都要在请求任何资源之前进行,所以任何Web应用在部署的时候,服务器就会调用Filter过滤器的init方法进行初始化,而关于过滤器的销毁,则是将该过滤器移除或者服务器关闭就会执行destory方法。
而我们通常要使用过滤器处理请求,则重点在于doFilter(…)方法。当请求要经过一个过滤器的时候,就会由服务器调用doFilter方法。
我们先来看看一个带有过滤器Filter的web应用的请求和响应流程:
记住:从请求到响应这个流程会经过Filter对象两次!
在doFilter这一个方法中就可以对着两次经过的过程进行处理,那么这里就有一个问题了,如果能通过过滤器,那么就到过滤器后面了,貌似应该是执行完doFilter方法了,而服务器的响应又经过过滤器,难道又要执行doFilter方法一次?但是这个方法里面的代码不是也有处理最开始请求的吗?
这就跟doFilter方法中的第三个参数FilterChain有关了,FilterChain对象是过滤器链,这个我们稍后会介绍。在FilterChain对象中只有一个方法:
=也是叫doFilter方法(千万别和Filter接口的doFilter方法弄混了)。简单的说下这个方法,只要调用了这个方法,就会将请求交给后面一个Filter进行过滤(一个Web应用中可以有多个Filter),如果该Filter是最后一个,那么调用该方法则将执行请求,也就是到我们的应用中获取资源。
因此从请求到响应这个流程经过Filter的两次处理分别是在FilterChain.doFilter方法的前面和后面!如下图所示:
那么下面我们就先以一个简单的例子来熟悉下Filter吧:
例1:
创建web工程FilterLearning,创建一个FilterDemo1类,同时这个类要实现javax.servlet.Filter接口。如下代码:
public class FilterDemo implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("hello filter"); } //此处省略init方法和destory方法 }写好Filter的Java代码还没完,还要在web应用下的web.xml文件中配置如下信息:
<filter> <filter-name>FilterDemo1</filter-name> <filter-class>com.bjpowernode.web.filter.FilterDemo</filter-class> </filter> <filter-mapping> <filter-name>FilterDemo1</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>注意:因为我在<url-pattern>中配置为“/*”,则访问我wen应用中任何资源都会经过该Filter过滤器。如果只想对于index.jsp主页的请求进行过滤,可以设为<url-pattern>/index.jsp</url-pattern>。
我们在index.jsp中简单的使用JSP脚本来演示如果有请求来就输入一段文本到控制台上:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML> <html> <head> <title>index</title> </head> <body> <% System.out.println("Long live SD !"); %> </body> </html>接下来将该web应用部署到服务器中,我们就访问index.jsp,以下是我们访问了index.jsp后控制台的情况:
首先,我们可以保证在我们访问index.jsp后这个请求确实经过了Filter过滤器,但是我们的请求好像就只到过滤器而没有到我们真正需要的资源index.jsp?这是因为我们没有在Filter的doFilter方法中调用过滤器链FilterChain对象的doFilter方法,自然无法将请求继续往后面传递。我们将在例2中修改。
例2:
我们将例1中的FilterDemo1类进行修改,使其能访问到我们所需要的资源,很简单,在doFilter的方法中添加过滤器链FilterChain对象的doFilter方法即可:
public class FilterDemo implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("hello filter"); chain.doFilter(request, response); } //此处省略init方法和destory方法 }其他如web.xml中的配置和index.jsp中的代码保持不变,现在我们再来访问下该web应用中的index.jsp,并观察控制台:
可以看到我们的请求经过过滤器,执行了过滤器的一段代码(System.out.println(“hello filter”)),然后将请求继续执行!正是因为FilterChain.doFilter方法才使我们通过过滤器继续向后寻找我们所需的资源。
那么还记得我们之前说过的从请求到响应会经过两次过滤器吗,是的在获取了我们所需的资源后还会到过滤器一趟,而至于这时候是否将响应再做处理取决于过滤器链FilterChain.doFilter方法后面还是否有代码。我们将在例3中完整的展现从请求到响应经过过滤器两次的流程。
例3:
我们将例2中的FilterDemo1类进行修改,只要在FilterChain.doFilter方法后面添加代码,就是第二次(即响应)经过过滤器所要执行的处理:
public class FilterDemo implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("hello filter"); chain.doFilter(request, response); System.out.println("goodbye filter"); } //此处省略init方法和destory方法 }其他如web.xml中的配置和index.jsp中的代码保持不变,现在我们再来访问下该web应用中的index.jsp,并观察控制台:
这个结果证明了从请求到响应确实经过过滤器两次,同时也说明了在Filter的doFilter方法中“过滤——取资源——再过滤”执行的顺序。
现在我们再回到Filter接口的init方法,我们可以看到在这个方法内有一个参数FilterConfig,这个是由服务器传给我们的对象。如果我们在web.xml文件中配置了过滤器的初始化参数,就可以通过该FilterConfig对象来在代码中获取使用。
这个过滤器参数的初始化配置可以在<filter>标签中配置<init-param>,并在这个<init-param>标签下再配置<param-name>和<param-value>。
FilterConfig有如下方法:
当然如果我们是要获取配置的初始化参数则只需关注getInitParameter方法或getInitParameterNames方法。
一般来说我们可以在init方法中获取配置初始化参数并进行处理;也可以通过对象引用将FilterConfig对象在doFilter方法中处理参数,如例4所示。
例4:
在web.xml文件中配置过滤器和初始化参数:
<filter> <filter-name>FilterDemo1</filter-name> <filter-class>com.bjpowernode.web.filter.FilterDemo1</filter-class> <init-param> <param-name>Love</param-name> <param-value>LRR</param-value> </init-param> </filter> <filter-mapping> <filter-name>FilterDemo1</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>在Java中编写Filter接口的实现类FilterDemo1:
public class FilterDemo implements Filter { private FilterConfig filterConfig ; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String value = filterConfig.getInitParameter("Love"); System.out.println(value); } @Override public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; } //此处省略destroy方法 }因为配置的原因,所以我们随便访问个资源都可以经过该过滤器,那么就访问index.jsp好了,看看控制台的结果:
正如我们在web.xml文件所配置的初始化参数一样。
上面介绍的都是只有一个Filter过滤器的情况下,有时候我们会因为要过滤的功能不同添加多个过滤器,这就有一个顺序的问题了,尤其是从取得资源后再返回到过滤器的顺序。下面这张图就能很清晰的看到我们要注意的顺序了:
例5:
来写两个Filter来说明下从请求到响应过滤器的处理顺序。
创建一个web工程,创建一个FilterDemo1类,同时这个类要实现javax.servlet.Filter接口。如下代码:
public class FilterDemo1 implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("Hello filter 1"); chain.doFilter(request, response); System.out.println("Goodbye filter 1"); } //此处省略init方法和destroy方法 }创建第二个Filter接口实现类FilterDemo2,代码如下:
public class FilterDemo2 implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("Hello filter 2"); chain.doFilter(request, response); System.out.println("Goodbye filter 2"); } //此处省略init方法和destroy方法 }过滤器要想能被服务器调用,还必须要在该web工程下的web.xml中配置过滤器及其映射,而这个配置的顺序就是影响多个过滤器工作先后的顺序:
<filter> <filter-name>FilterDemo1</filter-name> <filter-class>com.bjpowernode.web.filter.FilterDemo1</filter-class> </filter> <filter-mapping> <filter-name>FilterDemo1</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>FilterDemo2</filter-name> <filter-class>com.bjpowernode.web.filter.FilterDemo2</filter-class> </filter> <filter-mapping> <filter-name>FilterDemo2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>而我们要访问的资源文件就以index.jsp为例好了,那么我们用一段JSP脚本通过在控制台打印来验证过滤器工作的顺序过程:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML> <html> <head> <title>index</title> </head> <body> <% System.out.println("Long live SD !"); %> </body> </html>现在启动服务器,部署该工程,通过访问index.jsp来看看控制台情况:
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
java过滤器模式(Filter/CriteriaPattern)过滤器模式(FilterPattern)或标准模式(CriteriaPattern)是一种设计
1、过滤器的用法,用‘|'分割表达式和过滤器。例如:{{msg|filter}}{{msg|filter(a)}}a就标识filter的一个参数。用两个过滤器:
一过滤器写法{{message|Filter}}二Vue自带的过滤器:capitalize功能:首字母大写Vue自带的过滤器{{message|capitali
vue2.0里,不再有自带的过滤器,需要自己定义过滤器。定义的方法如下:注册一个自定义过滤器,它接收两个参数:过滤器ID和过滤器函数。Vue.filter('f
vue2.0里,不再有自带的过滤器,需要自己定义过滤器。定义的方法如下:注册一个自定义过滤器,它接收两个参数:过滤器ID和过滤器函数。Vue.filter('f