java-WEB中的过滤器Filter

过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上。过滤器可附加到一个或多个servlet或JSP页面上,并且可以检查进入这些资源的请求信息。
在这之后,过滤器可以作如下的选择:
  ①以常规的方式调用资源(即,调用servlet或JSP页面)。
  ②利用修改过的请求信息调用资源。
  ③调用资源,但在发送响应到客户机前对其进行修改。
  ④阻止该资源调用,代之以转到其他的资源,返回一个特定的状态代码或生成替换输出。


定义:必须实现javax.servlet.Filter接口.


public class ClearCacheFilter implements Filter {
public ClearCacheFilter() {
}


Servlet容器在卸载过滤器实例前调用该方法。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源.


public void destroy() {
}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
}

//这是Servlet过滤器的初始化方法.

在 web 应用程序启动时,web 服务器将根据 web.xml 文件中的配置信息来创建每个注册的 Filter实例对象,并将其保存在服务器的内存中。Web容器(servlet容器)创建 Filter 对象实例后,将立即调用该 Filter 对象的 init 方法


Init 方法在 Filter 生命周期中仅执行一次, servlet容器在调用init 方法时,会传递一个包含 Filter 的配置和运行环境的 FilterConfig 对象(FilterConfig的用法和ServletConfig类似)利用FilterConfig对象可以得到ServletContext对象,以及部署描述符中配置的过滤器的初始化参数

public void init(FilterConfig fConfig) throws ServletException {
}

注意: 1、doFilter方法 参数不是HttpServletRequest和HttpServletResponse,但是我们在servlet中,请求的一般是http协议,这 时,如果需要处理Http的请求,可以将ServletRequest 强制转换为HttpServletRequest,ServletResponse 强制装换为HttpServletResponse,然后进行处理,如设置Http响应头信息等.

2、与开发Servlet不同的是,Filter接口并没有相应的实现类可供继承,要开发过滤器,只能直接实现Filter接口


作用:Filter 的基本功能是对Servlet容器调用Servlet的过程进行拦截,

从而在 Servlet进行响应处理的前后实现一些特殊的功能。

1、在 Servlet API 中定义了三个接口类来开供开发人员编写 Filter程序:Filter, FilterChainFilterConfig.

2Filter 程序是一个实现了Filter接口的 Java 类,与 Servlet 程序相似,它由 Servlet 容器进行调用和执行.

3Filter 程序需要在 web.xml文件中进行注册和设置它所能拦截的资源:Filter 程序可以拦截 Jsp, Servlet, 静态图片文件和静态html 文件.


原理:

1、在过滤器使用时,它可以对客户的请求进行处理。处理完成后,它会交给下一个过滤器处理,这样,客户的请求在过滤链里逐个处理,直到请求发送到目标为止。

例如,某网站里有提交“修改的注册信息”的网页,当用户填写完修改信息并提交后,服务器在进行处理时需要做两项工作:判断客户端的会话是否有效对提交的数据进行统一编码。这两项工作可以在由两个过滤器组成的过滤链里进行处理。当过滤器处理成功后,把提交的数据发送到最终目标;如果过滤器处理不成功,将把视图派发到指定的错误页面。

2、在一个 web 应用程序中可以注册多个 Filter程序,每个Filter程序都可以对一个或一组Servlet程序进行拦截。

3、若有多个 Filter 程序对某个 Servlet程序的访问过程进行拦截,当针对该Servlet的访问请求到达时,web 容器将把这多个 Filter程序组合成一个Filter(过滤器链)Filter 链中各个 Filter的拦截顺序与它们在应用程序的web.xml中映射的顺序一致



FilterChain:

1、FilterChain接口:代表当前 Filter 链的对象。由容器实现,容器将其实例作为参数传入过滤器对象的doFilter()方法中。过滤器对象使用FilterChain对象调用过滤器链中的下一个过滤器,如果该过滤器是链中最后一个过滤器,那么将调用目标资源。

2、方法doFilter(ServletRequestrequest,ServletResponseresponse)throws java.io.IOException:调用该方法将使过滤器链中的下一个过滤器被调用。如果是最后一个过滤器,会调用目标资源。


FilterConfig:

1、javax.servlet.FilterConfig接口:该接口类似于ServletConfig接口,由容器实现。Servlet规范将代表ServletContext对象和Filter的配置参数信息都封装在该对象中。Servlet容器将其作为参数传入过滤器对象的init()方法中。

2、StringgetFilterName():得到描述符中指定的过滤器的名字。

3、StringgetInitParameter(String name): 返回在部署描述中指定的名字为name的初始化参数的值。如果不存在返回null.

4、Enumeration getInitParameterNames():返回过滤器的所有初始化参数的名字的枚举集合。

5、publicServletContext getServletContext():返回Servlet上下文对象的引用。


Filter的部署:通过<filter><filter-mapping>元素来完成。

<filter>元素
<filter>元素用于在Web应用程序中注册一个过滤器。
<filter>元素内
<filter-name>用于为过滤器指定一个名字,该元素的内容不能为空。
<filter-class>元素用于指定过滤器的完整的限定类名。
<init-param>元素用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名<param-value>指定参数的值。在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。
Servlet容器对部署描述符中声明的每一个过滤器,只创建一个实例。与Servlet类似,容器将在同一个过滤器实例上运行多个线程来同时为多个请求服务,因此,开发过滤器时,也要注意线程安全的问题


Filter映射:
<filter-mapping>元素用于设置一个 Filter所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet名称和资源访问的请求路径( url样式)
<filter-name>子元素用于设置filter的注册名称。该值必须是在
<filter>元素中声明过的过滤器的名字<url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)
<servlet-name>指定过滤器所拦截的Servlet名称。
<dispatcher>指定过滤器所拦截的资源被Servlet容器调用的方式,可以是REQUEST,INCLUDE,FORWARDERROR之一,默认REQUEST. 可以设置多个<dispatcher>子元素用来指定Filter对资源的多种调用方式进行拦截

filtermapping里面定义了对文件进行过滤,

1)、”/*”表示所有URL

2)、如果*.jsp表示对后缀是.jsp的文件进行过滤

3)、如果还有其他的页面,如.do或者.action等,那么可以继续添加

<filter-mapping>这个选项,其中<url-pattern>就填写*.do或者*.action即可。



配置示例:
<filter>

< filter-name>EncodingFilter</filter-name>

< filter-class>manyfilter.EncodingFilter</filter-class>

< init-param>

< param-name>encoding</param-name>

< param-value>utf-8</param-value>

< /init-param>

< init-param>

< param-name>blacklist</param-name>

< param-value>dao</param-value>

< /init-param>

</filter>

<filter-mapping>

< filter-name>EncodingFilter</filter-name>

< url-pattern>/test.jsp</url-pattern>

</filter-mapping>

<filter-mapping>

< filter-name>EncodingFilter</filter-name>

<url-pattern>*.do</url-pattern>

< dispatcher>REQUEST</dispatcher>

< dispatcher>FORWARD</dispatcher>

</filter-mapping>

Filter <dispatcher> 子元素:

<dispatcher>子元素可以设置的值及其意义:
REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcherinclude()forward()方法访问时,那么该过滤器就不会被调用。默认值
INCLUDE:如果目标资源是通过RequestDispatcherinclude()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
FORWARD:如果目标资源是通过RequestDispatcherforward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用

关于ERROR的解释:

ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

当我们访问一个web目标资源时,如果服务器没有找到该目标资源,那么服务器就会给出一个404错误代码。如果我们给404错误代码定义一个页面,那么当404错误发生时就会调用该页面,请看以下web.xml文件的配置:

  

<filter-mapping> 
< filter-name>myFilter</filter-name>
<url-pattern>/error.jsp</url-pattern>
< dispatcher>ERROR</dispatcher>
</filter-mapping> 


<error-page>
< error-code>404</error-code> 
< location>/error.jsp</location>
</error-page>

   当我们访问一个不存在的文件时,就会访问error.jsp,但是配置了过滤器对错误页面进行过滤,所以过滤器先接受到请求,然后再转发给error.jsp

你可能感兴趣的:(filter)