首页 > 编程知识 正文

Filter函数(Filter、FilterChain、FilterConfig)

时间:2023-05-06 13:52:43 阅读:123409 作者:4891

另一方面,Filter的基本工作原理1,Filter程序是实现特殊接口的Java类,与servlet类似,由servlet容器调用并执行。 在web.xml中注册servlet进行拦截处理时,可以确定是否将请求传递给servlet,以及是否修改请求和响应消息。 3 .如果在servlet容器启动servlet调用时发现已经注册了用于阻止servlet的Filter程序,则容器不会直接调用servlet的servlet方法,而是doFilter方法确定是否激活servlet方法4,但是,Filter.doFilter方法不直接调用servlet的service方法。 调用FilterChain.doFilter方法以激活目标servlet的service方法;对于FilterChain对象,调用通过Filter.doFilter方法5, 在Filter.doFilter方法中调用FilterChain.doFilter方法的语句前后添加一些程序代码,可以在servlet响应前后实现一些特殊功能。 6、如果在Filter.doFilter方法中未调用FilterChain.doFilter方法,则不会执行目标servlet的servlet方法,从而允许Filter阻止未经授权的访问请求。 二、过滤器链1,一个web APP应用可以注册多个过滤器程序,每个过滤器程序可以侦听一个或一组servlet程序。 如果有多个过滤器程序可以监听servlet的访问进程,则当访问该servlet的请求到达时,Web容器将这些多个过滤器程序划分为一个过滤器链(也称为过滤器链) 2、过滤器链中每个过滤器的拦截顺序与它们在web.xml文件中的映射顺序一致。 在上一个Filter.doFilter方法中调用FilterChain.doFilter方法时,下一个Filter的doFilter方法处于活动状态。 在最后一个Filter.doFilter方法中调用的FilterChain.doFilter方法激活目标servlet的servlet方法。 3、除非Filter链中的任何Filter调用FilterChain.doFilter方法,否则不会执行目标servlet的servlet方法。 三、过滤器接口一个过滤器程序是一个Java类,这个类必须实现过滤器接口。 javax.servlet.Filter界面定义了三种方法: init、doFilter和destory。

1、init 方法

) 1、Web APP应用程序启动后,Web服务器(web容器)根据web.xml文件的配置信息创建每个注册的Filter的实例对象,并将其保存到内存中。 ) 2、Web容器创建Filter的实例对象后,将立即调用该Filter对象的init方法。 init方法在Filter生命周期中只运行一次,Web容器在调用init方法时传递包含Filter配置和运行环境信息的FilterConfig对象。

publicvoicinit (文件配置文件配置) throws ServletException (3) 3开发人员可以在init方法中完成与构建方法类似的初始化功能。 将初始化代码用于filterconfig对象时请小心。 这些代码只能用init方法编写,不能用构造方法编写。 由于未调用init方法,即未创建FilterConfig对象,因此使用时会发生错误。 2、doFilter方法如果Filter对象可以侦听访问请求,servlet容器将调用Filter对象的doFilter方法。

publicvoiddofilter (servletrequestrequest,servlet响应响应,FilterChain chain ) throws Java.io.io exception.servlet 参数chain是表示当前过滤器链的对象。

3、destroy方法此方法在Web容器卸载Filter对象之前被调用,并且只执行一次。 可以完成与init方法相反的功能,以释放此Filter对象打开的资源,如数据库连接和关闭IO流。

四.过滤器通道接口此接口用于定义过滤器链中的对象应该对外提供的方式,该接口只定义了一个doFilter方法。

公共语音文档

ilter(ServletRequest request, ServletResponse response) throws java.io.IOException.ServletException

FilterChain 接口的 doFilter 方法用于通知 Web 容器把请求交给 Filter 链中的下一个 Filter 去处理,如果当前调用此方法的 Filter 对象是Filter 链中的最后一个 Filter,那么将把请求交给目标 Servlet 程序去处理。

五、FilterConfig 接口 1、与普通的 Servlet 程序一样,Filter 程序也很可能需要访问 Servlet 容器。Servlet 规范将代表 ServletContext 对象和 Filter 的配置参数信息都封装到一个称为 FilterConfig 的对象中。2、FilterConfig 接口则用于定义 FilterConfig 对象应该对外提供的方法,以便在 Filter 程序中可以调用这些方法来获取 ServletContext 对象,以及获取在 web.xml 文件中为 Filter 设置的友好名称和初始化参数。

3、FilterConfig接口定义的各个方法:

getFilterName 方法,返回 <filter-name> 元素的设置值。

getServletContext 方法,返回 FilterConfig 对象中所包装的 ServletContext 对象的引用。

getInitParameter 方法,用于返回在 web.xml 文件中为 Filter 所设置的某个名称的初始化的参数值。

getInitParameterNames 方法,返回一个 Enumeration 集合对象。

六、Filter 的注册与映射 1、注册 Filter

一个 <filter> 元素用于注册一个 Filter。其中,<filter-name> 元素是必需的,<filter-class> 元素也是必需的,<init-param> 元素是可选的,可以有多个 < init-param> 元素。

<filter> <filter-name>FirstFilter</filter-name> <filter-class>FirstFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>GB2312</param-value> </init-param></filter> 2、映射 Filter

<filter-mapping> 元素用于设置一个 Filter 所负责拦截的资源。一个 Filter 拦截的资源可以通过两种方式来指定:资源的访问请求路径和 Servlet 名称。

第一种:指定资源的访问路径

<filter-mapping> <filter-name>FirstFilter</filter-name> <url-pattern>/*</url-pattern></filter-mapping>

<url-pattern> 元素中的访问路径的设置方式遵循 Servlet 的 URL 映射规范。

/*:表示拦截所有的访问请求。/filter/*:表示拦截 filter 目录下的所有访问请求,如:http://localhost:8888/testFilter_001/filter/xxxxxx 。/test.html:表示拦截根目录下以 test.html 为资源名的访问请求,访问链接只会是:http://localhost:8888/test.html。

第二种:指定 Servlet 的名称

<filter-mapping> <filter-name>FirstFilter</filter-name> <servlet-name>default></servlet-name> <dispatcher>INCLUDE</dispatcher> <dispatcher>REQUEST</dispatcher></filter-mapping>

(1)、<servlet-name> 元素与 <url-pattern> 元素是二选一的关系,其值是某个 Servlet 在 web.xml 文件中的注册名称。

(2)、<dispatcher> 元素的设置值有 4 种:REQUEST、INCLUDE、FORWARD、ERROR,分别对应 Servlet 容器调用资源的 4 种方式:

通过正常的访问请求调用;

通过 RequestDispatcher.include 方法调用;

通过 RequestDispatcher.forward 方法调用;

作为错误响应资源调用。

如果没有设置 <dispatcher> 子元素,则等效于 REQUEST 的情况。也可以设置多个 <dispatcher> 子元素,用于指定 Filter 对资源的多种调用方式都进行拦截。

七、Filter 程序示例 FitstFilter.java

import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; public class FirstFilter implements Filter { private FilterConfig filterConfig = null; String paramValue = null; @Override public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; paramValue = filterConfig.getInitParameter("encoding"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("begin headers-------------------"); Enumeration<?> headerNames = ((HttpServletRequest)request).getHeaderNames(); while(headerNames.hasMoreElements()) { String headerName = (String)headerNames.nextElement(); System.out.println(headerName + ": " + ((HttpServletRequest)request).getHeader(headerName)); } System.out.println("end headers-------------------"); //在调用目标前写入响应内容 response.setContentType("text/html; charset=gb2312"); PrintWriter out = response.getWriter(); out.println("IP地址为:" + request.getRemoteHost() + "<br>"); chain.doFilter(request, response); //在目标返回后写入响应内容 out.println("<br>名称为encoding的初始化参数的值为:" + paramValue); out.println("<br>当前Web程序的真实路径为:" + filterConfig.getServletContext().getRealPath("/")); //out.println("<br>修改了test.html文件!"); } @Override public void destroy() { this.filterConfig = null; } }

web.xml

<filter> <filter-name>FirstFilter</filter-name> <filter-class>FirstFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>GB2312</param-value> </init-param> </filter> <filter-mapping> <filter-name>FirstFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

test.html(位于WebContent路径的filter目录中)

<html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> 这就是test.html页面的原始内容! </body> </html>

访问:http://localhost:8888/testFilter_001/filter/test.html

文章来源:https://my.oschina.net/u/1171518/blog/265467

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。