java web学习:三大组件 Filter基础

java web中的Filter是用来对Http请求进行过滤,比如过滤掉非法访问、字符编码处理等。

一 、过滤器例子

1、Filter接口的介绍

在java web中定义过滤器,只需要定义一个实现Filter接口的类就行。在Filter接口中有三个方法。

package javax.servlet;

import java.io.IOException;


public interface Filter {

    
    public void init(FilterConfig filterConfig) throws ServletException;
    

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


    public void destroy();
}

public void doFilter (ServletRequest, ServletResponse, FilterChain):该方法完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain用户访问后续过滤器

 public void init(FilterConfig filterConfig):web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次)。开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。

public void destroy():Servlet容器在销毁过滤器实例前调用该方法,在该方法中释放Servlet过滤器占用的资源。

2 、 过滤器定义

package com.web.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class MyFilter implements Filter{
    
    static {
        System.out.println("过滤器开始加载");
    }
    public MyFilter(){
        System.out.println("过滤器开始实例化");
    }
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器开始初始化");
        
    }

    @Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
            throws IOException, ServletException {
        System.out.println("过滤请求");
        arg2.doFilter(arg0, arg1);
    }
    
    @Override
    public void destroy() {
        System.out.println("过滤请求完成");
        Filter.super.destroy();
    }

}

3、过滤器的配置

可以在web.xml配置,在Servlet 3.0标准之后可以采用SPI方式进行注册,也可以采用注解方式,此处采用web.xml方式进行注册

<!-- 注册过滤器 -->
    <filter>
        <filter-name>myFilter</filter-name>
        <filter-class>com.web.filter.MyFilter</filter-class>
        <init-param>
            <param-name>param01</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>param02</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>myFilter</filter-name>
        <url-pattern>/myServlet</url-pattern>
    </filter-mapping>

在一个 web 应用中,可以开发编写多个 Filter,这些 Filter 组合起来称之为一个 Filter 链。web 服务器根据 Filter 在 web.xml 文件中的注册顺序,决定先调用哪个 Filter,当第一个 Filter 的 doFilter 方法被调用时,web 服务器会创建一个代表 Filter 链的 filterChain 对象传递给该方法。在 doFilter 方法中,开发人员如果调用了 filterChain 对象的 doFilter 方法,则 web 服务器会检查 FilterChain 对象中是否还有 Filter,如果有,则调用第 2 个 Filter;如果没有,则调用目标资源。

4、Filter 的生命周期

Filter 的创建和销毁由 web 服务器负责。 web 应用程序启动时,web 服务器将创建 Filter 的实例对象,并调用其 init 方法,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作,Filter 对象只会创建一次,init 方法也只会执行一次。通过 init 方法的参数,可获得代表当前 Filter 配置信息 FilterConfig 对象。web 容器调用 destroy 方法销毁 Filter,destroy 方法在 Filter 的生命周期中仅执行一次。在 destroy 方法中,可以释放过滤器使用的资源。

用户在配置 Filter 时,可以使用init-param为 Filter 配置一些初始化参数,当 web 容器实例化 Filter 对象,调用其 init 方法时,会把封装了 Filter 初始化参数的 FilterConfig 对象传递进来。因此开发人员在编写 Filter 时,通过 FilterConfig 对象的方法,就可获得:

  • String getFilterName():得到 Filter 的名称;
  • String getInitParameter(String name):返回在部署描述中指定名称的初始化参数的值,如果不存在,则返回 null;
  • Enumeration getInitParameterNames():返回过滤器的所有初始化参数的名字的枚举集合;
  • public ServletContext getServletContext():返回 Servlet 上下文对象的引用。

5、<filter-mapping>标签下的<dispatcher>

dispatcher:指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUESTINCLUDEFORWARDERROR之一,默认为REQUEST,用户可以设置多个dispatcher子元素用来指定 Filter 对资源的多种调用方式进行拦截。例如:

<filter-mapping>
        <filter-name>myFilter</filter-name>
        <url-pattern>/myServlet</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

dispatcher子元素可以设置的值及其意义:

  • REQUEST:当用户直接访问页面时,web 容器将会调用过滤器,如果目标资源是通过 RequestDispatcher 的 include() 或 forward() 方法访问时,那么该过滤器就不会被调用;
  • INCLUDE:如果目标资源是通过 RequestDispatcher 的 include() 方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用;
  • FORWARD:如果目标资源是通过 RequestDispatcher 的 forward() 方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用;
  • ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。

 

原文地址:https://www.cnblogs.com/cplinux/p/12426856.html